Mod boundary constraint func & Separate parameter model & Add parameter component #36
| @ -1,8 +1,8 @@ | |||||||
| import { BehaviorRecorder, IAnyBehaviorRecorder } from "@Model/Behavior"; | import { BehaviorRecorder, IAnyBehaviorRecorder } from "@Model/Behavior"; | ||||||
| import { Template } from "./Template"; | import { Template } from "@Behavior/Template"; | ||||||
| import { Dynamics } from "./Dynamics"; | import { Dynamics } from "@Behavior/Dynamics"; | ||||||
| import { Brownian } from "./Brownian"; | import { Brownian } from "@Behavior/Brownian"; | ||||||
| import { BoundaryConstraint } from "./BoundaryConstraint";  | import { BoundaryConstraint } from "@Behavior/BoundaryConstraint"; | ||||||
| 
 | 
 | ||||||
| const AllBehaviors: IAnyBehaviorRecorder[] = [ | const AllBehaviors: IAnyBehaviorRecorder[] = [ | ||||||
|     new BehaviorRecorder(Template), |     new BehaviorRecorder(Template), | ||||||
|  | |||||||
| @ -1,12 +1,12 @@ | |||||||
| import { Behavior } from "@Model/Behavior"; | import { Behavior } from "@Model/Behavior"; | ||||||
| import { Group } from "@Model/Group"; | import { Group } from "@Model/Group"; | ||||||
| import { Individual } from "@Model/Individual"; | import { Individual } from "@Model/Individual"; | ||||||
| import { Label } from "@Model/Label"; |  | ||||||
| import { Model } from "@Model/Model"; | import { Model } from "@Model/Model"; | ||||||
| import { Range } from "@Model/Range"; | import { Range } from "@Model/Range"; | ||||||
| 
 | 
 | ||||||
| type IBoundaryConstraintBehaviorParameter = { | type IBoundaryConstraintBehaviorParameter = { | ||||||
|     range: "LR" |     range: "LR", | ||||||
|  | 	strength: "number" | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| type IBoundaryConstraintBehaviorEvent = {} | type IBoundaryConstraintBehaviorEvent = {} | ||||||
| @ -27,6 +27,13 @@ class BoundaryConstraint extends Behavior<IBoundaryConstraintBehaviorParameter, | |||||||
| 		range: { | 		range: { | ||||||
| 			type: "LR", | 			type: "LR", | ||||||
| 			name: "$range" | 			name: "$range" | ||||||
|  | 		}, | ||||||
|  | 		strength: { | ||||||
|  | 			type: "number", | ||||||
|  | 			name: "$Strength", | ||||||
|  | 			defaultValue: 1, | ||||||
|  |             numberMin: 0, | ||||||
|  |             numberStep: .1 | ||||||
| 		} | 		} | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| @ -35,6 +42,14 @@ class BoundaryConstraint extends Behavior<IBoundaryConstraintBehaviorParameter, | |||||||
|             "ZH_CN": "边界约束", |             "ZH_CN": "边界约束", | ||||||
|             "EN_US": "Boundary constraint" |             "EN_US": "Boundary constraint" | ||||||
|         }, |         }, | ||||||
|  | 		"$range": { | ||||||
|  | 			"ZH_CN": "约束范围", | ||||||
|  | 			"EN_US": "Constraint range" | ||||||
|  | 		}, | ||||||
|  | 		"$Strength": { | ||||||
|  | 			"ZH_CN": "约束强度系数", | ||||||
|  | 			"EN_US": "Restraint strength coefficient" | ||||||
|  | 		}, | ||||||
|         "$Intro": { |         "$Intro": { | ||||||
|             "ZH_CN": "个体越出边界后将主动返回", |             "ZH_CN": "个体越出边界后将主动返回", | ||||||
|             "EN_US": "Individuals will return actively after crossing the border" |             "EN_US": "Individuals will return actively after crossing the border" | ||||||
| @ -43,6 +58,12 @@ class BoundaryConstraint extends Behavior<IBoundaryConstraintBehaviorParameter, | |||||||
| 
 | 
 | ||||||
|     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; | ||||||
|  | 
 | ||||||
|  | 		let fx = 0; | ||||||
|  | 		let fy = 0; | ||||||
|  | 		let fz = 0; | ||||||
|  | 		let fLen = Infinity; | ||||||
|  | 
 | ||||||
| 		for (let i = 0; i < rangeList.length; i++) { | 		for (let i = 0; i < rangeList.length; i++) { | ||||||
| 
 | 
 | ||||||
| 			let rx = rangeList[i].position[0] - individual.position[0]; | 			let rx = rangeList[i].position[0] - individual.position[0]; | ||||||
| @ -53,12 +74,30 @@ class BoundaryConstraint extends Behavior<IBoundaryConstraintBehaviorParameter, | |||||||
| 			let oy = Math.abs(ry) > rangeList[i].radius[1]; | 			let oy = Math.abs(ry) > rangeList[i].radius[1]; | ||||||
| 			let oz = Math.abs(rz) > rangeList[i].radius[2]; | 			let oz = Math.abs(rz) > rangeList[i].radius[2]; | ||||||
| 
 | 
 | ||||||
| 			individual.applyForce( | 			if (ox || oy || oz) { | ||||||
| 				ox ? rx : 0, | 
 | ||||||
| 				oy ? ry : 0, | 				let currentFLen = individual.vectorLength(rx, ry, rz); | ||||||
| 				oz ? rz : 0 | 				if (currentFLen < fLen) { | ||||||
| 			) | 					fx = rx; | ||||||
|  | 					fy = ry; | ||||||
|  | 					fz = rz; | ||||||
|  | 					fLen = currentFLen; | ||||||
| 				} | 				} | ||||||
|  | 
 | ||||||
|  | 			} else { | ||||||
|  | 
 | ||||||
|  | 				fx = 0; | ||||||
|  | 				fy = 0; | ||||||
|  | 				fz = 0; | ||||||
|  | 				fLen = 0; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		individual.applyForce( | ||||||
|  | 			fx * this.parameter.strength, | ||||||
|  | 			fy * this.parameter.strength, | ||||||
|  | 			fz * this.parameter.strength | ||||||
|  | 		); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -49,7 +49,7 @@ class Dynamics extends Behavior<IDynamicsBehaviorParameter, IDynamicsBehaviorEve | |||||||
| 		resistance: { | 		resistance: { | ||||||
| 			name: "$Resistance", | 			name: "$Resistance", | ||||||
| 			type: "number", | 			type: "number", | ||||||
| 			defaultValue: 0.1, | 			defaultValue: 0.5, | ||||||
| 			numberStep: .1, | 			numberStep: .1, | ||||||
| 			numberMin: 0 | 			numberMin: 0 | ||||||
| 		} | 		} | ||||||
| @ -76,6 +76,10 @@ class Dynamics extends Behavior<IDynamicsBehaviorParameter, IDynamicsBehaviorEve | |||||||
| 			"ZH_CN": "最大速度 (m/s)", | 			"ZH_CN": "最大速度 (m/s)", | ||||||
|             "EN_US": "Maximum velocity (m/s)" |             "EN_US": "Maximum velocity (m/s)" | ||||||
| 		}, | 		}, | ||||||
|  | 		"$Resistance": { | ||||||
|  | 			"ZH_CN": "阻力系数", | ||||||
|  | 			"EN_US": "Resistance coefficient" | ||||||
|  | 		}, | ||||||
| 		"$Physics": { | 		"$Physics": { | ||||||
| 			"ZH_CN": "物理", | 			"ZH_CN": "物理", | ||||||
|             "EN_US": "Physics" |             "EN_US": "Physics" | ||||||
|  | |||||||
| @ -1,11 +1,13 @@ | |||||||
| import { Theme } from "@Component/Theme/Theme"; |  | ||||||
| import { Component, ReactNode } from "react"; | import { Component, ReactNode } from "react"; | ||||||
| import { IRenderBehavior, Behavior, BehaviorRecorder } from "@Model/Behavior"; | import { Icon } from "@fluentui/react"; | ||||||
| import { useSettingWithEvent, IMixinSettingProps } from "@Context/Setting"; | import { useSettingWithEvent, IMixinSettingProps } from "@Context/Setting"; | ||||||
| import { useStatus, IMixinStatusProps } from "@Context/Status"; | import { useStatus, IMixinStatusProps } from "@Context/Status"; | ||||||
| import { Icon } from "@fluentui/react"; | import { IRenderBehavior, Behavior, BehaviorRecorder } from "@Model/Behavior"; | ||||||
|  | import { Theme } from "@Component/Theme/Theme"; | ||||||
| import { ConfirmPopup } from "@Component/ConfirmPopup/ConfirmPopup"; | import { ConfirmPopup } from "@Component/ConfirmPopup/ConfirmPopup"; | ||||||
| import { Message } from "@Component/Message/Message"; | import { Message } from "@Input/Message/Message"; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| import "./BehaviorList.scss"; | import "./BehaviorList.scss"; | ||||||
| 
 | 
 | ||||||
| interface IBehaviorListProps { | interface IBehaviorListProps { | ||||||
|  | |||||||
| @ -1,15 +1,15 @@ | |||||||
| import { Component, ReactNode, Fragment } from "react"; | import { Component, ReactNode, Fragment } from "react"; | ||||||
| import { Popup } from "@Context/Popups"; | import { Popup } from "@Context/Popups"; | ||||||
|  | import { useStatus, IMixinStatusProps, randomColor } from "@Context/Status"; | ||||||
|  | import { useSettingWithEvent, IMixinSettingProps } from "@Context/Setting"; | ||||||
| import { Localization } from "@Component/Localization/Localization"; | import { Localization } from "@Component/Localization/Localization"; | ||||||
| import { SearchBox } from "@Component/SearchBox/SearchBox"; | import { SearchBox } from "@Input/SearchBox/SearchBox"; | ||||||
| import { ConfirmContent } from "@Component/ConfirmPopup/ConfirmPopup"; | import { ConfirmContent } from "@Component/ConfirmPopup/ConfirmPopup"; | ||||||
| import { BehaviorList } from "@Component/BehaviorList/BehaviorList"; | import { BehaviorList } from "@Component/BehaviorList/BehaviorList"; | ||||||
| import { AllBehaviorsWithCategory, ICategoryBehavior } from "@Behavior/Behavior"; | import { AllBehaviorsWithCategory, ICategoryBehavior } from "@Behavior/Behavior"; | ||||||
| import { Message } from "@Component/Message/Message"; | import { Message } from "@Input/Message/Message"; | ||||||
| import { IRenderBehavior, BehaviorRecorder } from "@Model/Behavior"; | import { IRenderBehavior, BehaviorRecorder } from "@Model/Behavior"; | ||||||
| import { useStatus, IMixinStatusProps, randomColor } from "@Context/Status"; | 
 | ||||||
| import { useSettingWithEvent, IMixinSettingProps } from "@Context/Setting"; |  | ||||||
| import { ConfirmPopup } from "@Component/ConfirmPopup/ConfirmPopup"; |  | ||||||
| import "./BehaviorPopup.scss"; | import "./BehaviorPopup.scss"; | ||||||
| 
 | 
 | ||||||
| interface IBehaviorPopupProps { | interface IBehaviorPopupProps { | ||||||
|  | |||||||
| @ -1,12 +1,12 @@ | |||||||
| import { BackgroundLevel, Theme } from "@Component/Theme/Theme"; | import { Component, ReactNode } from "react"; | ||||||
| import { DirectionalHint, IconButton } from "@fluentui/react"; | import { DirectionalHint, IconButton } from "@fluentui/react"; | ||||||
| import { LocalizationTooltipHost } from "../Localization/LocalizationTooltipHost"; |  | ||||||
| import { useSetting, IMixinSettingProps } from "@Context/Setting"; | import { useSetting, IMixinSettingProps } from "@Context/Setting"; | ||||||
| import { useStatusWithEvent, IMixinStatusProps } from "@Context/Status"; | import { useStatusWithEvent, IMixinStatusProps } from "@Context/Status"; | ||||||
| import { AllI18nKeys } from "../Localization/Localization"; | import { BackgroundLevel, Theme } from "@Component/Theme/Theme"; | ||||||
| import { SettingPopup } from "../SettingPopup/SettingPopup"; | import { LocalizationTooltipHost } from "@Component/Localization/LocalizationTooltipHost"; | ||||||
| import { BehaviorPopup } from "../BehaviorPopup/BehaviorPopup"; | import { AllI18nKeys } from "@Component/Localization/Localization"; | ||||||
| import { Component, ReactNode } from "react"; | import { SettingPopup } from "@Component/SettingPopup/SettingPopup"; | ||||||
|  | import { BehaviorPopup } from "@Component/BehaviorPopup/BehaviorPopup"; | ||||||
| import { MouseMod } from "@GLRender/ClassicRenderer"; | import { MouseMod } from "@GLRender/ClassicRenderer"; | ||||||
| import "./CommandBar.scss"; | import "./CommandBar.scss"; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| import { Popup } from "@Context/Popups"; |  | ||||||
| import { Component, ReactNode } from "react"; | import { Component, ReactNode } from "react"; | ||||||
| import { Message } from "@Component/Message/Message"; | import { Popup } from "@Context/Popups"; | ||||||
|  | import { Message } from "@Input/Message/Message"; | ||||||
| import { Theme } from "@Component/Theme/Theme"; | import { Theme } from "@Component/Theme/Theme"; | ||||||
| import { AllI18nKeys, Localization } from "@Component/Localization/Localization"; | import { AllI18nKeys, Localization } from "@Component/Localization/Localization"; | ||||||
| import "./ConfirmPopup.scss"; | import "./ConfirmPopup.scss"; | ||||||
|  | |||||||
| @ -1,11 +1,11 @@ | |||||||
| import { Localization } from "@Component/Localization/Localization"; |  | ||||||
| import { Theme, BackgroundLevel, FontLevel } from "@Component/Theme/Theme"; |  | ||||||
| import { Themes } from "@Context/Setting"; |  | ||||||
| import { DirectionalHint } from "@fluentui/react"; |  | ||||||
| import { ILayout, LayoutDirection } from "@Context/Layout"; |  | ||||||
| import { Component, ReactNode, MouseEvent } from "react"; | import { Component, ReactNode, MouseEvent } from "react"; | ||||||
| import { getPanelById, getPanelInfoById } from "../../Panel/Panel"; | import { DirectionalHint } from "@fluentui/react"; | ||||||
| import { LocalizationTooltipHost } from "../Localization/LocalizationTooltipHost"; | import { Themes } from "@Context/Setting"; | ||||||
|  | import { ILayout, LayoutDirection } from "@Context/Layout"; | ||||||
|  | import { Localization } from "@Component/Localization/Localization"; | ||||||
|  | import { BackgroundLevel, FontLevel } from "@Component/Theme/Theme"; | ||||||
|  | import { getPanelById, getPanelInfoById } from "@Panel/Panel"; | ||||||
|  | import { LocalizationTooltipHost } from "@Component/Localization/LocalizationTooltipHost"; | ||||||
| import "./Container.scss"; | import "./Container.scss"; | ||||||
| 
 | 
 | ||||||
| interface IContainerProps extends ILayout { | interface IContainerProps extends ILayout { | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| import { Icon } from "@fluentui/react"; |  | ||||||
| import { Component, ReactNode } from "react"; | import { Component, ReactNode } from "react"; | ||||||
| import { BackgroundLevel, FontLevel, Theme } from "../Theme/Theme"; | import { Icon } from "@fluentui/react"; | ||||||
|  | import { BackgroundLevel, FontLevel, Theme } from "@Component/Theme/Theme"; | ||||||
| import "./DetailsList.scss"; | import "./DetailsList.scss"; | ||||||
| 
 | 
 | ||||||
| type IItems = Record<string, any> & {key: string, select?: boolean}; | type IItems = Record<string, any> & {key: string, select?: boolean}; | ||||||
|  | |||||||
| @ -1,12 +1,11 @@ | |||||||
| import { Component, ReactNode } from "react"; | import { Component, ReactNode } from "react"; | ||||||
|  | import { Icon } from '@fluentui/react/lib/Icon'; | ||||||
| import { useStatus, IMixinStatusProps } from "@Context/Status"; | import { useStatus, IMixinStatusProps } from "@Context/Status"; | ||||||
| import { useSetting, IMixinSettingProps } from "@Context/Setting"; | import { useSetting, IMixinSettingProps } from "@Context/Setting"; | ||||||
| import { Theme, BackgroundLevel, FontLevel } from "@Component/Theme/Theme"; | import { Theme, BackgroundLevel, FontLevel } from "@Component/Theme/Theme"; | ||||||
| import { Icon } from '@fluentui/react/lib/Icon'; | import { LocalizationTooltipHost } from "@Component/Localization/LocalizationTooltipHost"; | ||||||
| import { LocalizationTooltipHost } from "../Localization/LocalizationTooltipHost"; | import { I18N } from "@Component/Localization/Localization"; | ||||||
| import { I18N } from "../Localization/Localization"; |  | ||||||
| import "./HeaderBar.scss"; | import "./HeaderBar.scss"; | ||||||
| import { Tooltip, TooltipHost } from "@fluentui/react"; |  | ||||||
| 
 | 
 | ||||||
| interface IHeaderBarProps { | interface IHeaderBarProps { | ||||||
|     height: number; |     height: number; | ||||||
|  | |||||||
| @ -1,7 +1,7 @@ | |||||||
| import { Component, RefObject } from "react"; | import { Component, RefObject } from "react"; | ||||||
| import { Label } from "@Model/Label"; |  | ||||||
| import { Icon } from "@fluentui/react"; | import { Icon } from "@fluentui/react"; | ||||||
| import { useSetting, IMixinSettingProps, Themes } from "@Context/Setting"; | import { useSetting, IMixinSettingProps, Themes } from "@Context/Setting"; | ||||||
|  | import { Label } from "@Model/Label"; | ||||||
| import "./LabelList.scss"; | import "./LabelList.scss"; | ||||||
| 
 | 
 | ||||||
| interface ILabelListProps { | interface ILabelListProps { | ||||||
|  | |||||||
| @ -78,4 +78,4 @@ class Localization extends Component<ILocalizationProps & IMixinSettingProps & | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export { Localization, I18N, LanguageDataBase, AllI18nKeys }; | export { Localization, I18N, LanguageDataBase, AllI18nKeys, ILocalizationProps }; | ||||||
| @ -1,9 +1,9 @@ | |||||||
| import { Component, ReactNode } from "react"; | import { Component, ReactNode } from "react"; | ||||||
|  | import { Icon } from "@fluentui/react"; | ||||||
| import { IMixinStatusProps, useStatusWithEvent } from "@Context/Status"; | import { IMixinStatusProps, useStatusWithEvent } from "@Context/Status"; | ||||||
| import { IMixinSettingProps, useSettingWithEvent } from "@Context/Setting"; | import { IMixinSettingProps, useSettingWithEvent } from "@Context/Setting"; | ||||||
| import { BackgroundLevel, FontLevel, getClassList, Theme } from "@Component/Theme/Theme"; | import { BackgroundLevel, FontLevel, getClassList, Theme } from "@Component/Theme/Theme"; | ||||||
| import { Popup as PopupModel, ResizeDragDirection } from "@Context/Popups"; | import { Popup as PopupModel, ResizeDragDirection } from "@Context/Popups"; | ||||||
| import { Icon } from "@fluentui/react"; |  | ||||||
| import "./Popup.scss"; | import "./Popup.scss"; | ||||||
| 
 | 
 | ||||||
| interface IPopupProps {} | interface IPopupProps {} | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| import { useSettingWithEvent, Themes, IMixinSettingProps, Setting } from "@Context/Setting"; |  | ||||||
| import { Component, ReactNode, DetailedHTMLProps, HTMLAttributes } from "react"; | import { Component, ReactNode, DetailedHTMLProps, HTMLAttributes } from "react"; | ||||||
|  | import { useSettingWithEvent, Themes, IMixinSettingProps, Setting } from "@Context/Setting"; | ||||||
| import "./Theme.scss"; | import "./Theme.scss"; | ||||||
| 
 | 
 | ||||||
| enum FontLevel { | enum FontLevel { | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| import { Emitter, EventType } from "@Model/Emitter"; |  | ||||||
| import { Component, FunctionComponent, ReactNode, Consumer } from "react"; | import { Component, FunctionComponent, ReactNode, Consumer } from "react"; | ||||||
|  | import { Emitter, EventType } from "@Model/Emitter"; | ||||||
| 
 | 
 | ||||||
| type RenderComponent = (new (...p: any) => Component<any, any, any>) | FunctionComponent<any>; | type RenderComponent = (new (...p: any) => Component<any, any, any>) | FunctionComponent<any>; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,7 +1,7 @@ | |||||||
| import { createContext } from "react"; | import { createContext } from "react"; | ||||||
| import { superConnect, superConnectWithEvent } from "./Context"; | import { superConnect, superConnectWithEvent } from "@Context/Context"; | ||||||
| import { Emitter } from "@Model/Emitter"; | import { Emitter } from "@Model/Emitter"; | ||||||
| import { Layout } from "./Layout"; | import { Layout } from "@Context/Layout"; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * 主题模式 |  * 主题模式 | ||||||
|  | |||||||
| @ -7,11 +7,12 @@ import { Group } from "@Model/Group"; | |||||||
| import { Archive } from "@Model/Archive"; | import { Archive } from "@Model/Archive"; | ||||||
| import { AbstractRenderer } from "@Model/Renderer"; | import { AbstractRenderer } from "@Model/Renderer"; | ||||||
| import { ClassicRenderer, MouseMod } from "@GLRender/ClassicRenderer"; | import { ClassicRenderer, MouseMod } from "@GLRender/ClassicRenderer"; | ||||||
| import { Setting } from "./Setting"; | import { Setting } from "@Context/Setting"; | ||||||
| import { I18N } from "@Component/Localization/Localization"; | import { I18N } from "@Component/Localization/Localization"; | ||||||
| import { superConnectWithEvent, superConnect } from "./Context"; | import { superConnectWithEvent, superConnect } from "@Context/Context"; | ||||||
| import { PopupController } from "./Popups"; | import { PopupController } from "@Context/Popups"; | ||||||
| import { Behavior, IBehaviorParameter, IParamValue } from "@Model/Behavior"; | import { Behavior } from "@Model/Behavior"; | ||||||
|  | import { IParameter, IParamValue } from "@Model/Parameter"; | ||||||
| import { Actuator } from "@Model/Actuator"; | import { Actuator } from "@Model/Actuator"; | ||||||
| 
 | 
 | ||||||
| function randomColor(unNormal: boolean = false) { | function randomColor(unNormal: boolean = false) { | ||||||
| @ -208,7 +209,7 @@ class Status extends Emitter<IStatusEvent> { | |||||||
|     /** |     /** | ||||||
|      * 修改群属性 |      * 修改群属性 | ||||||
|      */ |      */ | ||||||
|     public changeBehaviorAttrib<K extends IBehaviorParameter, P extends keyof K | keyof Behavior<K>> |     public changeBehaviorAttrib<K extends IParameter, P extends keyof K | keyof Behavior<K>> | ||||||
|     (id: ObjectID, key: P, val: IParamValue<K[P]>, noParameter?: boolean) { |     (id: ObjectID, key: P, val: IParamValue<K[P]>, noParameter?: boolean) { | ||||||
|         const behavior = this.model.getBehaviorById(id); |         const behavior = this.model.getBehaviorById(id); | ||||||
|         if (behavior) { |         if (behavior) { | ||||||
|  | |||||||
| @ -1,4 +1,4 @@ | |||||||
| @import "../Theme/Theme.scss"; | @import "../../Component/Theme/Theme.scss"; | ||||||
| 
 | 
 | ||||||
| $line-min-height: 24px; | $line-min-height: 24px; | ||||||
| 
 | 
 | ||||||
| @ -1,8 +1,8 @@ | |||||||
| import { Component, ReactNode } from "react"; | import { Component, ReactNode } from "react"; | ||||||
| import { Icon } from "@fluentui/react"; | import { Icon } from "@fluentui/react"; | ||||||
| import { Localization, AllI18nKeys } from "@Component/Localization/Localization"; | import { AllI18nKeys } from "@Component/Localization/Localization"; | ||||||
| import { ObjectID } from "@Model/Renderer"; | import { ObjectID } from "@Model/Renderer"; | ||||||
| import { TextField, ITextFieldProps } from "../TextField/TextField"; | import { TextField, ITextFieldProps } from "@Input/TextField/TextField"; | ||||||
| import "./AttrInput.scss"; | import "./AttrInput.scss"; | ||||||
| 
 | 
 | ||||||
| interface IAttrInputProps extends ITextFieldProps { | interface IAttrInputProps extends ITextFieldProps { | ||||||
| @ -1,4 +1,4 @@ | |||||||
| @import "../Theme/Theme.scss"; | @import "../../Component/Theme/Theme.scss"; | ||||||
| 
 | 
 | ||||||
| div.behavior-picker-list { | div.behavior-picker-list { | ||||||
|     width: 100%; |     width: 100%; | ||||||
| @ -1,11 +1,11 @@ | |||||||
| import { DetailsList } from "@Component/DetailsList/DetailsList"; |  | ||||||
| import { Component, ReactNode, createRef } from "react"; | import { Component, ReactNode, createRef } from "react"; | ||||||
| import { Behavior } from "@Model/Behavior"; |  | ||||||
| import { Icon } from "@fluentui/react"; | import { Icon } from "@fluentui/react"; | ||||||
|  | import { Behavior } from "@Model/Behavior"; | ||||||
| import { useSettingWithEvent, IMixinSettingProps } from "@Context/Setting"; | import { useSettingWithEvent, IMixinSettingProps } from "@Context/Setting"; | ||||||
| import { useStatusWithEvent, IMixinStatusProps } from "@Context/Status"; | import { useStatusWithEvent, IMixinStatusProps } from "@Context/Status"; | ||||||
|  | import { DetailsList } from "@Component/DetailsList/DetailsList"; | ||||||
| import { Localization } from "@Component/Localization/Localization"; | import { Localization } from "@Component/Localization/Localization"; | ||||||
| import { PickerList } from "@Component/PickerList/PickerList"; | import { PickerList } from "@Input/PickerList/PickerList"; | ||||||
| import "./BehaviorPicker.scss"; | import "./BehaviorPicker.scss"; | ||||||
| 
 | 
 | ||||||
| interface IBehaviorPickerProps { | interface IBehaviorPickerProps { | ||||||
| @ -1,6 +1,6 @@ | |||||||
| import { Component, createRef, ReactNode } from "react"; | import { Component, createRef, ReactNode } from "react"; | ||||||
| import { TextField, ITextFieldProps } from "@Component/TextField/TextField"; |  | ||||||
| import { Callout, ColorPicker, DirectionalHint } from "@fluentui/react"; | import { Callout, ColorPicker, DirectionalHint } from "@fluentui/react"; | ||||||
|  | import { TextField, ITextFieldProps } from "@Input/TextField/TextField"; | ||||||
| import "./ColorInput.scss"; | import "./ColorInput.scss"; | ||||||
| 
 | 
 | ||||||
| interface IColorInputProps extends ITextFieldProps { | interface IColorInputProps extends ITextFieldProps { | ||||||
| @ -1,4 +1,4 @@ | |||||||
| @import "../Theme/Theme.scss"; | @import "../../Component/Theme/Theme.scss"; | ||||||
| 
 | 
 | ||||||
| $line-min-height: 24px; | $line-min-height: 24px; | ||||||
| 
 | 
 | ||||||
| @ -1,7 +1,7 @@ | |||||||
| import { Component, createRef, ReactNode } from "react"; | import { Component, createRef, ReactNode } from "react"; | ||||||
| import { PickerList, IDisplayItem } from "../PickerList/PickerList"; |  | ||||||
| import { TextField, ITextFieldProps } from "../TextField/TextField"; |  | ||||||
| import { Icon } from "@fluentui/react"; | import { Icon } from "@fluentui/react"; | ||||||
|  | import { PickerList, IDisplayItem } from "@Input/PickerList/PickerList"; | ||||||
|  | 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"; | ||||||
| interface IComboInputProps extends ITextFieldProps { | interface IComboInputProps extends ITextFieldProps { | ||||||
| @ -1,4 +1,4 @@ | |||||||
| @import "../Theme/Theme.scss"; | @import "../../Component/Theme/Theme.scss"; | ||||||
| 
 | 
 | ||||||
| $line-min-height: 26px; | $line-min-height: 26px; | ||||||
| 
 | 
 | ||||||
| @ -1,9 +1,9 @@ | |||||||
| import { PickerList } from "../PickerList/PickerList"; |  | ||||||
| import { Label } from "@Model/Label"; |  | ||||||
| import { TextField, ITextFieldProps } from "../TextField/TextField"; |  | ||||||
| import { useStatusWithEvent, IMixinStatusProps } from "@Context/Status"; |  | ||||||
| import { Component, ReactNode, createRef } from "react"; | import { Component, ReactNode, createRef } from "react"; | ||||||
| import { LabelList } from "../LabelList/LabelList"; | import { Label } from "@Model/Label"; | ||||||
|  | import { PickerList } from "@Input/PickerList/PickerList"; | ||||||
|  | import { TextField, ITextFieldProps } from "@Input/TextField/TextField"; | ||||||
|  | import { useStatusWithEvent, IMixinStatusProps } from "@Context/Status"; | ||||||
|  | import { LabelList } from "@Component/LabelList/LabelList"; | ||||||
| import "./LabelPicker.scss" | import "./LabelPicker.scss" | ||||||
| 
 | 
 | ||||||
| interface ILabelPickerProps extends ITextFieldProps { | interface ILabelPickerProps extends ITextFieldProps { | ||||||
| @ -1,6 +1,6 @@ | |||||||
|  | import { FunctionComponent } from "react"; | ||||||
| import { AllI18nKeys, I18N } from "@Component/Localization/Localization"; | import { AllI18nKeys, I18N } from "@Component/Localization/Localization"; | ||||||
| import { useSettingWithEvent, IMixinSettingProps, Themes, Language } from "@Context/Setting"; | import { useSettingWithEvent, IMixinSettingProps, Themes, Language } from "@Context/Setting"; | ||||||
| import { FunctionComponent } from "react"; |  | ||||||
| import "./Message.scss"; | import "./Message.scss"; | ||||||
| 
 | 
 | ||||||
| interface IMessageProps { | interface IMessageProps { | ||||||
| @ -1,4 +1,4 @@ | |||||||
| @import "../Theme/Theme.scss"; | @import "../../Component/Theme/Theme.scss"; | ||||||
| @import "../PickerList/RainbowBg.scss"; | @import "../PickerList/RainbowBg.scss"; | ||||||
| 
 | 
 | ||||||
| $line-min-height: 24px; | $line-min-height: 24px; | ||||||
| @ -1,14 +1,14 @@ | |||||||
| import { Component, createRef, ReactNode } from "react"; | import { Component, createRef, ReactNode } from "react"; | ||||||
|  | import { useStatusWithEvent, IMixinStatusProps } from "@Context/Status"; | ||||||
| import { Label } from "@Model/Label"; | import { Label } from "@Model/Label"; | ||||||
| import { Group } from "@Model/Group"; | import { Group } from "@Model/Group"; | ||||||
| import { Range } from "@Model/Range"; | import { Range } from "@Model/Range"; | ||||||
| import { TextField, ITextFieldProps } from "../TextField/TextField"; |  | ||||||
| import { useStatusWithEvent, IMixinStatusProps } from "@Context/Status"; |  | ||||||
| import { PickerList, IDisplayItem, getObjectDisplayInfo, IDisplayInfo } from "../PickerList/PickerList"; |  | ||||||
| import { Localization } from "@Component/Localization/Localization"; |  | ||||||
| import { Icon } from "@fluentui/react"; |  | ||||||
| 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 { PickerList, IDisplayItem, getObjectDisplayInfo, IDisplayInfo } from "@Input/PickerList/PickerList"; | ||||||
|  | import { Localization } from "@Component/Localization/Localization"; | ||||||
|  | import { Icon } from "@fluentui/react"; | ||||||
| import "./ObjectPicker.scss"; | import "./ObjectPicker.scss"; | ||||||
| 
 | 
 | ||||||
| type IObjectType = Label | Group | Range | CtrlObject; | type IObjectType = Label | Group | Range | CtrlObject; | ||||||
							
								
								
									
										0
									
								
								source/Input/Parameter/Parameter.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								source/Input/Parameter/Parameter.scss
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										202
									
								
								source/Input/Parameter/Parameter.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										202
									
								
								source/Input/Parameter/Parameter.tsx
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,202 @@ | |||||||
|  | import { Component, Fragment, ReactNode } from "react"; | ||||||
|  | import { useSettingWithEvent, IMixinSettingProps, Language } from "@Context/Setting"; | ||||||
|  | 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 { Message } from "@Input/Message/Message"; | ||||||
|  | import { | ||||||
|  |     IParameter, IParameterOption, IParameterOptionItem, | ||||||
|  |     IParameterValue, IParamValue, isObjectType, isVectorType | ||||||
|  | } from "@Model/Parameter"; | ||||||
|  | import "./Parameter.scss"; | ||||||
|  | 
 | ||||||
|  | interface IParameterProps<P extends IParameter = {}> { | ||||||
|  |     option: IParameterOption<P>; | ||||||
|  |     value: IParameterValue<P>; | ||||||
|  |     key: ObjectID; | ||||||
|  |     change: <K extends keyof P>(key: K, val: IParamValue<P[K]>) => any; | ||||||
|  |     i18n: <K extends keyof P>(option: IParameterOptionItem<P[K]>, language: Language) => string; | ||||||
|  |     title?: AllI18nKeys; | ||||||
|  |     titleOption?: Record<string, string>; | ||||||
|  |     isFirst?: boolean; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @useSettingWithEvent("language") | ||||||
|  | class Parameter<P extends IParameter> extends Component<IParameterProps<P> & IMixinSettingProps> { | ||||||
|  | 
 | ||||||
|  |     private renderParameter<K extends keyof P> | ||||||
|  |     (key: K, option: IParameterOptionItem<P[K]>, value: IParamValue<P[K]>): ReactNode { | ||||||
|  | 
 | ||||||
|  |         const indexKey = `${this.props.key}-${key}`; | ||||||
|  |         const type = option.type; | ||||||
|  |         const i18nString = this.props.i18n(option, this.props.setting?.language ?? "EN_US"); | ||||||
|  | 
 | ||||||
|  |         if (type === "number") { | ||||||
|  |             return <AttrInput | ||||||
|  |                 key={indexKey} | ||||||
|  |                 id={indexKey} | ||||||
|  |                 keyI18n="Panel.Info.Behavior.Details.Parameter.Key" | ||||||
|  |                 keyI18nOption={{ key: i18nString }} | ||||||
|  |                 isNumber={true} | ||||||
|  |                 step={option.numberStep} | ||||||
|  |                 maxLength={option.maxLength} | ||||||
|  |                 max={option.numberMax} | ||||||
|  |                 min={option.numberMin} | ||||||
|  |                 value={value as IParamValue<"number"> ?? 0} | ||||||
|  |                 valueChange={(val) => { | ||||||
|  |                     this.props.change(key, parseFloat(val) as IParamValue<P[K]>); | ||||||
|  |                 }} | ||||||
|  |             />; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         else if (type === "string") { | ||||||
|  |             return <AttrInput | ||||||
|  |                 key={indexKey} | ||||||
|  |                 id={indexKey} | ||||||
|  |                 keyI18n="Panel.Info.Behavior.Details.Parameter.Key" | ||||||
|  |                 keyI18nOption={{ key: i18nString }} | ||||||
|  |                 maxLength={option.maxLength} | ||||||
|  |                 value={value as IParamValue<"string"> ?? ""} | ||||||
|  |                 valueChange={(val) => { | ||||||
|  |                     this.props.change(key, val as IParamValue<P[K]>); | ||||||
|  |                 }} | ||||||
|  |             />; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         else if (type === "boolean") { | ||||||
|  |             return <TogglesInput | ||||||
|  |                 key={indexKey} | ||||||
|  |                 keyI18n="Panel.Info.Behavior.Details.Parameter.Key" | ||||||
|  |                 keyI18nOption={{ key: i18nString }} | ||||||
|  | 				onIconName={option.iconName} | ||||||
|  |                 value={value as IParamValue<"boolean"> ?? false} | ||||||
|  | 				valueChange={(val) => { | ||||||
|  | 					this.props.change(key, val as IParamValue<P[K]>); | ||||||
|  | 				}} | ||||||
|  | 			/> | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         else if (isObjectType(type)) { | ||||||
|  | 
 | ||||||
|  |             type IObjectParamValue = IParamValue<"G" | "R" | "LG" | "LR">; | ||||||
|  |             const typedValue = value as IObjectParamValue; | ||||||
|  | 
 | ||||||
|  |             return <ObjectPicker | ||||||
|  |                 key={indexKey} | ||||||
|  |                 keyI18n="Panel.Info.Behavior.Details.Parameter.Key" | ||||||
|  |                 keyI18nOption={{ key: i18nString }} | ||||||
|  |                 type={type} | ||||||
|  |                 value={typedValue.picker} | ||||||
|  |                 valueChange={(obj) => { | ||||||
|  |                     typedValue.picker = obj as IObjectParamValue["picker"]; | ||||||
|  |                     this.props.change(key, typedValue as IParamValue<P[K]>); | ||||||
|  |                 }} | ||||||
|  |                 cleanValue={() => { | ||||||
|  |                     typedValue.picker = undefined as IObjectParamValue["picker"]; | ||||||
|  |                     this.props.change(key, typedValue as IParamValue<P[K]>); | ||||||
|  |                 }} | ||||||
|  |             /> | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         else if (isVectorType(type)) { | ||||||
|  | 
 | ||||||
|  |             type IObjectParamValue = IParamValue<"vec">; | ||||||
|  |             const typedValue = value as IObjectParamValue; | ||||||
|  |              | ||||||
|  |             return <Fragment key={indexKey}> | ||||||
|  |                  | ||||||
|  |                 <AttrInput | ||||||
|  |                     key={`${indexKey}-X`} | ||||||
|  |                     id={indexKey} | ||||||
|  |                     keyI18n="Panel.Info.Behavior.Details.Parameter.Key.Vec.X" | ||||||
|  |                     keyI18nOption={{ key: i18nString }} | ||||||
|  |                     isNumber={true} | ||||||
|  |                     step={option.numberStep} | ||||||
|  |                     maxLength={option.maxLength} | ||||||
|  |                     max={option.numberMax} | ||||||
|  |                     min={option.numberMin} | ||||||
|  |                     value={typedValue[0] ?? 0} | ||||||
|  |                     valueChange={(val) => { | ||||||
|  |                         typedValue[0] = parseFloat(val); | ||||||
|  |                         this.props.change(key, typedValue as IParamValue<P[K]>); | ||||||
|  |                     }} | ||||||
|  |                 /> | ||||||
|  | 
 | ||||||
|  |                 <AttrInput | ||||||
|  |                     key={`${indexKey}-Y`} | ||||||
|  |                     id={indexKey} | ||||||
|  |                     keyI18n="Panel.Info.Behavior.Details.Parameter.Key.Vec.Y" | ||||||
|  |                     keyI18nOption={{ key: i18nString }} | ||||||
|  |                     isNumber={true} | ||||||
|  |                     step={option.numberStep} | ||||||
|  |                     maxLength={option.maxLength} | ||||||
|  |                     max={option.numberMax} | ||||||
|  |                     min={option.numberMin} | ||||||
|  |                     value={typedValue[1] ?? 0} | ||||||
|  |                     valueChange={(val) => { | ||||||
|  |                         typedValue[1] = parseFloat(val); | ||||||
|  |                         this.props.change(key, typedValue as IParamValue<P[K]>); | ||||||
|  |                     }} | ||||||
|  |                 /> | ||||||
|  | 
 | ||||||
|  |                 <AttrInput | ||||||
|  |                     key={`${indexKey}-Z`} | ||||||
|  |                     id={indexKey} | ||||||
|  |                     keyI18n="Panel.Info.Behavior.Details.Parameter.Key.Vec.Z" | ||||||
|  |                     keyI18nOption={{ key: i18nString }} | ||||||
|  |                     isNumber={true} | ||||||
|  |                     step={option.numberStep} | ||||||
|  |                     maxLength={option.maxLength} | ||||||
|  |                     max={option.numberMax} | ||||||
|  |                     min={option.numberMin} | ||||||
|  |                     value={typedValue[2] ?? 0} | ||||||
|  |                     valueChange={(val) => { | ||||||
|  |                         typedValue[2] = parseFloat(val); | ||||||
|  |                         this.props.change(key, typedValue as IParamValue<P[K]>); | ||||||
|  |                     }} | ||||||
|  |                 /> | ||||||
|  | 
 | ||||||
|  |             </Fragment> | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         else { | ||||||
|  |             return <Fragment key={indexKey}/> | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private renderAllParameter(key: Array<keyof P>) { | ||||||
|  |         return key.map((key) => { | ||||||
|  |             return this.renderParameter( | ||||||
|  |                 key, | ||||||
|  |                 this.props.option[key], | ||||||
|  |                 this.props.value[key], | ||||||
|  |             ); | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     public render(): ReactNode { | ||||||
|  |         const allOptionKeys: Array<keyof P> = Object.getOwnPropertyNames(this.props.option); | ||||||
|  |          | ||||||
|  |         return <> | ||||||
|  |          | ||||||
|  |             { | ||||||
|  |                 allOptionKeys.length <= 0 && this.props.title ? | ||||||
|  |                     <Message | ||||||
|  |                         isTitle | ||||||
|  |                         first={this.props.isFirst} | ||||||
|  |                         i18nKey={this.props.title} | ||||||
|  |                         options={this.props.titleOption} | ||||||
|  |                     /> : null | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             { | ||||||
|  |                 this.renderAllParameter(allOptionKeys) | ||||||
|  |             } | ||||||
|  |          | ||||||
|  |         </> | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export { Parameter } | ||||||
| @ -1,4 +1,4 @@ | |||||||
| @import "../Theme/Theme.scss"; | @import "../../Component/Theme/Theme.scss"; | ||||||
| 
 | 
 | ||||||
| $search-box-height: 26px; | $search-box-height: 26px; | ||||||
| 
 | 
 | ||||||
| @ -1,8 +1,8 @@ | |||||||
|  | import { Component, ReactNode } from "react"; | ||||||
|  | import { Icon } from "@fluentui/react"; | ||||||
| import { AllI18nKeys, I18N } from "@Component/Localization/Localization"; | import { AllI18nKeys, I18N } from "@Component/Localization/Localization"; | ||||||
| import { BackgroundLevel, FontLevel, Theme } from "@Component/Theme/Theme"; | import { BackgroundLevel, FontLevel, Theme } from "@Component/Theme/Theme"; | ||||||
| import { useSettingWithEvent, IMixinSettingProps } from "@Context/Setting"; | import { useSettingWithEvent, IMixinSettingProps } from "@Context/Setting"; | ||||||
| import { Icon } from "@fluentui/react"; |  | ||||||
| import { Component, ReactNode } from "react"; |  | ||||||
| import "./SearchBox.scss"; | import "./SearchBox.scss"; | ||||||
| 
 | 
 | ||||||
| interface ISearchBoxProps { | interface ISearchBoxProps { | ||||||
| @ -1,4 +1,4 @@ | |||||||
| @import "../Theme/Theme.scss"; | @import "../../Component/Theme/Theme.scss"; | ||||||
| 
 | 
 | ||||||
| $line-min-height: 26px; | $line-min-height: 26px; | ||||||
| 
 | 
 | ||||||
| @ -1,4 +1,4 @@ | |||||||
| @import "../Theme/Theme.scss"; | @import "../../Component/Theme/Theme.scss"; | ||||||
| 
 | 
 | ||||||
| $line-min-height: 26px; | $line-min-height: 26px; | ||||||
| 
 | 
 | ||||||
| @ -1,6 +1,6 @@ | |||||||
| import { Icon } from "@fluentui/react"; |  | ||||||
| import { Component, ReactNode } from "react"; | import { Component, ReactNode } from "react"; | ||||||
| import { TextField, ITextFieldProps } from "../TextField/TextField"; | import { Icon } from "@fluentui/react"; | ||||||
|  | import { TextField, ITextFieldProps } from "@Input/TextField/TextField"; | ||||||
| import "./TogglesInput.scss"; | import "./TogglesInput.scss"; | ||||||
| 
 | 
 | ||||||
| interface ITogglesInputProps extends ITextFieldProps { | interface ITogglesInputProps extends ITextFieldProps { | ||||||
| @ -25,7 +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": "选择对象 ...", | ||||||
|     "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}", | ||||||
|     "Object.List.No.Data": "模型中没有任何对象,点击按钮以创建", |     "Object.List.No.Data": "模型中没有任何对象,点击按钮以创建", | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| import { Model } from "./Model"; | import { Model } from "@Model/Model"; | ||||||
| import { Emitter } from "./Emitter";  | import { Emitter } from "@Model/Emitter"; | ||||||
| 
 | 
 | ||||||
| interface IActuatorEvent { | interface IActuatorEvent { | ||||||
| 	startChange: boolean; | 	startChange: boolean; | ||||||
|  | |||||||
| @ -1,4 +1,4 @@ | |||||||
| import { Emitter, EventType, EventMixin } from "./Emitter"; | import { Emitter, EventType } from "@Model/Emitter"; | ||||||
| 
 | 
 | ||||||
| interface IArchiveEvent { | interface IArchiveEvent { | ||||||
|     save: Archive; |     save: Archive; | ||||||
|  | |||||||
| @ -1,136 +1,16 @@ | |||||||
| import { IAnyObject } from "./Renderer"; | import { Emitter, EventType } from "@Model/Emitter"; | ||||||
| import { Emitter, EventType } from "./Emitter"; | import type { Individual } from "@Model/Individual"; | ||||||
| import type { Individual } from "./Individual"; | import type { Group } from "@Model/Group"; | ||||||
| import type { Group } from "./Group"; | import type { Model } from "@Model/Model"; | ||||||
| import type { Model } from "./Model"; | import { getDefaultValue, IParameter, IParameterOption, IParameterValue } from "@Model/Parameter"; | ||||||
| import type { Range } from "./Range"; |  | ||||||
| import type { Label } from "./Label"; |  | ||||||
| 
 |  | ||||||
| type IObjectParamCacheType<P, Q = P> = { |  | ||||||
|     picker: P; |  | ||||||
|     objects: Q; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * 参数类型 |  | ||||||
|  */ |  | ||||||
| type IMapBasicParamTypeKeyToType = { |  | ||||||
|     "number": number; |  | ||||||
|     "string": string; |  | ||||||
|     "boolean": boolean; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type IMapObjectParamTypeKeyToType = { |  | ||||||
|     "R": IObjectParamCacheType<Range | undefined>; |  | ||||||
|     "G": IObjectParamCacheType<Group | undefined>; |  | ||||||
|     "LR": IObjectParamCacheType<Label | Range | undefined, Range[]>; |  | ||||||
|     "LG": IObjectParamCacheType<Label | Group | undefined, Group[]>; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| type IMapVectorParamTypeKeyToType = { |  | ||||||
|     "vec": number[]; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * 参数类型映射 |  | ||||||
|  */ |  | ||||||
| type AllMapType = IMapBasicParamTypeKeyToType & IMapObjectParamTypeKeyToType & IMapVectorParamTypeKeyToType; |  | ||||||
| type IParamType = keyof AllMapType; |  | ||||||
| type IObjectType = keyof IMapObjectParamTypeKeyToType; |  | ||||||
| type IVectorType = keyof IMapVectorParamTypeKeyToType; |  | ||||||
| type IParamValue<K extends IParamType> = AllMapType[K]; |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * 特殊对象类型判定 |  | ||||||
|  */ |  | ||||||
| const objectTypeListEnumSet = new Set<IParamType>(["R", "G", "LR", "LG"]); |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * 对象断言表达式 |  | ||||||
|  */ |  | ||||||
| function isObjectType(key: IParamType): key is IVectorType { |  | ||||||
|     return objectTypeListEnumSet.has(key); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * 向量断言表达式 |  | ||||||
|  */ |  | ||||||
| function isVectorType(key: IParamType): key is IObjectType { |  | ||||||
|     return key === "vec"; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * 模型参数类型 |  | ||||||
|  */ |  | ||||||
| interface IBehaviorParameterOptionItem<T extends IParamType = IParamType> { |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 参数类型 |  | ||||||
|      */ |  | ||||||
|     type: T | string; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 参数默认值 |  | ||||||
|      */ |  | ||||||
|     defaultValue?: IParamValue<T>; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 数值变化回调 |  | ||||||
|      */ |  | ||||||
|     onChange?: (value: IParamValue<T>) => any; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 名字 |  | ||||||
|      */ |  | ||||||
|     name: string; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 字符长度 |  | ||||||
|      */ |  | ||||||
|     maxLength?: number; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 数字步长 |  | ||||||
|      */ |  | ||||||
|     numberStep?: number; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 最大值最小值 |  | ||||||
|      */ |  | ||||||
|     numberMax?: number; |  | ||||||
|     numberMin?: number; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 图标名字 |  | ||||||
|      */ |  | ||||||
|     iconName?: string; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| interface IBehaviorParameter { |  | ||||||
|     [x: string]: IParamType; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * 参数类型列表 |  | ||||||
|  */ |  | ||||||
| type IBehaviorParameterOption<P extends IBehaviorParameter> = { |  | ||||||
|     [X in keyof P]: IBehaviorParameterOptionItem<P[X]>; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * 参数类型列表映射到参数对象 |  | ||||||
|  */ |  | ||||||
| type IBehaviorParameterValue<P extends IBehaviorParameter> = { |  | ||||||
|     [X in keyof P]: IParamValue<P[X]> |  | ||||||
| } |  | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * 行为构造函数类型 |  * 行为构造函数类型 | ||||||
|  */ |  */ | ||||||
| type IBehaviorConstructor< | type IBehaviorConstructor< | ||||||
|     P extends IBehaviorParameter = {}, |     P extends IParameter = {}, | ||||||
|     E extends Record<EventType, any> = {} |     E extends Record<EventType, any> = {} | ||||||
| > = new (id: string, parameter: IBehaviorParameterValue<P>) => Behavior<P, E>; | > = new (id: string, parameter: IParameterValue<P>) => Behavior<P, E>; | ||||||
| 
 | 
 | ||||||
| type IAnyBehavior = Behavior<any, any>; | type IAnyBehavior = Behavior<any, any>; | ||||||
| type IAnyBehaviorRecorder = BehaviorRecorder<any, any>; | type IAnyBehaviorRecorder = BehaviorRecorder<any, any>; | ||||||
| @ -192,7 +72,7 @@ class BehaviorInfo<E extends Record<EventType, any> = {}> extends Emitter<E> { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| class BehaviorRecorder< | class BehaviorRecorder< | ||||||
|     P extends IBehaviorParameter = {}, |     P extends IParameter = {}, | ||||||
|     E extends Record<EventType, any> = {} |     E extends Record<EventType, any> = {} | ||||||
| > extends BehaviorInfo<{}> { | > extends BehaviorInfo<{}> { | ||||||
| 
 | 
 | ||||||
| @ -221,62 +101,13 @@ class BehaviorRecorder< | |||||||
|     /** |     /** | ||||||
|      * 对象参数列表 |      * 对象参数列表 | ||||||
|      */ |      */ | ||||||
|     public parameterOption: IBehaviorParameterOption<P>; |     public parameterOption: IParameterOption<P>; | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 获取参数列表的默认值 |  | ||||||
|      */ |  | ||||||
|     public getDefaultValue(): IBehaviorParameterValue<P> { |  | ||||||
|         let defaultObj = {} as IBehaviorParameterValue<P>; |  | ||||||
|         for (let key in this.parameterOption) { |  | ||||||
|             let defaultVal = this.parameterOption[key].defaultValue; |  | ||||||
|              |  | ||||||
|             defaultObj[key] = defaultVal as any; |  | ||||||
|             if (defaultObj[key] === undefined) { |  | ||||||
| 
 |  | ||||||
|                 switch (this.parameterOption[key].type) { |  | ||||||
|                     case "string": |  | ||||||
|                         defaultObj[key] = "" as any; |  | ||||||
|                         break; |  | ||||||
| 
 |  | ||||||
|                     case "number": |  | ||||||
|                         defaultObj[key] = 0 as any; |  | ||||||
|                         break; |  | ||||||
| 
 |  | ||||||
|                     case "boolean": |  | ||||||
|                         defaultObj[key] = false as any; |  | ||||||
|                         break; |  | ||||||
| 
 |  | ||||||
|                     case "vec": |  | ||||||
|                         defaultObj[key] = [0, 0, 0] as any; |  | ||||||
|                         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; |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         return defaultObj; |  | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * 创建一个新的行为实例 |      * 创建一个新的行为实例 | ||||||
|      */ |      */ | ||||||
|     public new(): Behavior<P, E> { |     public new(): Behavior<P, E> { | ||||||
|         return new this.behavior(this.getNextId(), this.getDefaultValue()); |         return new this.behavior(this.getNextId(), getDefaultValue(this.parameterOption)); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public constructor(behavior: IBehaviorConstructor<P, E>) { |     public constructor(behavior: IBehaviorConstructor<P, E>) { | ||||||
| @ -297,7 +128,7 @@ class BehaviorRecorder< | |||||||
|  * 群体的某种行为 |  * 群体的某种行为 | ||||||
|  */ |  */ | ||||||
| class Behavior< | class Behavior< | ||||||
|     P extends IBehaviorParameter = {}, |     P extends IParameter = {}, | ||||||
|     E extends Record<EventType, any> = {} |     E extends Record<EventType, any> = {} | ||||||
| > extends BehaviorInfo<E> { | > extends BehaviorInfo<E> { | ||||||
| 
 | 
 | ||||||
| @ -325,14 +156,14 @@ class Behavior< | |||||||
|     /** |     /** | ||||||
|      * 行为参数 |      * 行为参数 | ||||||
|      */ |      */ | ||||||
|     public parameter: IBehaviorParameterValue<P>; |     public parameter: IParameterValue<P>; | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * 对象参数列表 |      * 对象参数列表 | ||||||
|      */ |      */ | ||||||
|     public parameterOption: IBehaviorParameterOption<P> = {} as any; |     public parameterOption: IParameterOption<P> = {} as any; | ||||||
| 
 | 
 | ||||||
|     public constructor(id: string, parameter: IBehaviorParameterValue<P>) { |     public constructor(id: string, parameter: IParameterValue<P>) { | ||||||
|         super(); |         super(); | ||||||
|         this.id = id; |         this.id = id; | ||||||
|         this.parameter = parameter; |         this.parameter = parameter; | ||||||
| @ -416,8 +247,6 @@ class Behavior< | |||||||
| type IRenderBehavior = BehaviorInfo | Behavior; | type IRenderBehavior = BehaviorInfo | Behavior; | ||||||
| 
 | 
 | ||||||
| export { | export { | ||||||
|     Behavior, BehaviorRecorder, IBehaviorParameterOption, IBehaviorParameterOptionItem, IParamValue, |     Behavior, BehaviorRecorder, IAnyBehavior, IAnyBehaviorRecorder, BehaviorInfo, IRenderBehavior | ||||||
|     IAnyBehavior, IAnyBehaviorRecorder, BehaviorInfo, IRenderBehavior, IBehaviorParameter, |  | ||||||
|     isObjectType, isVectorType |  | ||||||
| }; | }; | ||||||
| export default { Behavior }; | export default { Behavior }; | ||||||
| @ -1,6 +1,6 @@ | |||||||
| import { LabelObject } from "./Label" | import { LabelObject } from "@Model/Label" | ||||||
| import type { Model } from "./Model"; | import type { Model } from "@Model/Model"; | ||||||
| import type { ObjectID } from "./Renderer"; | import type { ObjectID } from "@Model/Renderer"; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * 可控对象 |  * 可控对象 | ||||||
|  | |||||||
| @ -1,8 +1,8 @@ | |||||||
| import { Individual } from "./Individual"; | import { Individual } from "@Model/Individual"; | ||||||
| import { CtrlObject } from "./CtrlObject"; | import { CtrlObject } from "@Model/CtrlObject"; | ||||||
| import type { Behavior } from "./Behavior";  | import type { Behavior } from "@Model/Behavior";  | ||||||
| import { Label } from "./Label"; | import { Label } from "@Model/Label"; | ||||||
| import { Range } from "./Range"; | import { Range } from "@Model/Range"; | ||||||
| 
 | 
 | ||||||
| enum GenMod { | enum GenMod { | ||||||
|     Point = "p", |     Point = "p", | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| import type { Group } from "./Group"; | import type { Group } from "@Model/Group"; | ||||||
| import { ObjectID } from "./Renderer"; | import { ObjectID } from "@Model/Renderer"; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * 群中的个体类型 |  * 群中的个体类型 | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| import type { Model } from "./Model"; | import type { Model } from "@Model/Model"; | ||||||
| import { ObjectID } from "./Renderer"; | import { ObjectID } from "@Model/Renderer"; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * 数据标签 |  * 数据标签 | ||||||
|  | |||||||
| @ -1,11 +1,12 @@ | |||||||
| import { Individual } from "./Individual"; | import { Label } from "@Model/Label"; | ||||||
| import { Group } from "./Group"; | import { Group } from "@Model/Group"; | ||||||
| import { Range } from "./Range"; | import { Range } from "@Model/Range"; | ||||||
| import { Emitter, EventType, EventMixin } from "./Emitter"; | import { IParamValue } from "@Model/Parameter"; | ||||||
| import { CtrlObject } from "./CtrlObject"; | import { Individual } from "@Model/Individual"; | ||||||
| import { ObjectID, AbstractRenderer } from "./Renderer"; | import { CtrlObject } from "@Model/CtrlObject"; | ||||||
| import { Label } from "./Label"; | import { Emitter, EventType, EventMixin } from "@Model/Emitter"; | ||||||
| import { Behavior, IAnyBehavior, IAnyBehaviorRecorder, IParamValue } from "./Behavior"; | import { ObjectID, AbstractRenderer } from "@Model/Renderer"; | ||||||
|  | import { Behavior, IAnyBehavior, IAnyBehaviorRecorder } from "@Model/Behavior"; | ||||||
| 
 | 
 | ||||||
| type ModelEvent = { | type ModelEvent = { | ||||||
|     labelChange: Label[]; |     labelChange: Label[]; | ||||||
|  | |||||||
							
								
								
									
										173
									
								
								source/Model/Parameter.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										173
									
								
								source/Model/Parameter.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,173 @@ | |||||||
|  | import type { Group } from "@Model/Group"; | ||||||
|  | import type { Range } from "@Model/Range"; | ||||||
|  | import type { Label } from "@Model/Label"; | ||||||
|  | 
 | ||||||
|  | type IObjectParamCacheType<P, Q = P> = { | ||||||
|  |     picker: P; | ||||||
|  |     objects: Q; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * 参数类型 | ||||||
|  |  */ | ||||||
|  | type IMapBasicParamTypeKeyToType = { | ||||||
|  |     "number": number; | ||||||
|  |     "string": string; | ||||||
|  |     "boolean": boolean; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | type IMapObjectParamTypeKeyToType = { | ||||||
|  |     "R": IObjectParamCacheType<Range | undefined>; | ||||||
|  |     "G": IObjectParamCacheType<Group | undefined>; | ||||||
|  |     "LR": IObjectParamCacheType<Label | Range | undefined, Range[]>; | ||||||
|  |     "LG": IObjectParamCacheType<Label | Group | undefined, Group[]>; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | type IMapVectorParamTypeKeyToType = { | ||||||
|  |     "vec": number[]; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * 参数类型映射 | ||||||
|  |  */ | ||||||
|  | type AllMapType = IMapBasicParamTypeKeyToType & IMapObjectParamTypeKeyToType & IMapVectorParamTypeKeyToType; | ||||||
|  | type IParamType = keyof AllMapType; | ||||||
|  | type IObjectType = keyof IMapObjectParamTypeKeyToType; | ||||||
|  | type IVectorType = keyof IMapVectorParamTypeKeyToType; | ||||||
|  | type IParamValue<K extends IParamType> = AllMapType[K]; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * 特殊对象类型判定 | ||||||
|  |  */ | ||||||
|  | const objectTypeListEnumSet = new Set<string>(["R", "G", "LR", "LG"]); | ||||||
|  | 
 | ||||||
|  |  /** | ||||||
|  |   * 对象断言表达式 | ||||||
|  |   */ | ||||||
|  | function isObjectType(key: string): key is IVectorType { | ||||||
|  |     return objectTypeListEnumSet.has(key); | ||||||
|  | } | ||||||
|  |   | ||||||
|  |  /** | ||||||
|  |   * 向量断言表达式 | ||||||
|  |   */ | ||||||
|  | function isVectorType(key: string): key is IObjectType { | ||||||
|  |     return key === "vec"; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * 模型参数类型 | ||||||
|  |  */ | ||||||
|  | interface IParameterOptionItem<T extends IParamType = IParamType> { | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 参数类型 | ||||||
|  |      */ | ||||||
|  |     type: T | string; | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 参数默认值 | ||||||
|  |      */ | ||||||
|  |     defaultValue?: IParamValue<T>; | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 数值变化回调 | ||||||
|  |      */ | ||||||
|  |     onChange?: (value: IParamValue<T>) => any; | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 名字 | ||||||
|  |      */ | ||||||
|  |     name: string; | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 字符长度 | ||||||
|  |      */ | ||||||
|  |     maxLength?: number; | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 数字步长 | ||||||
|  |      */ | ||||||
|  |     numberStep?: number; | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 最大值最小值 | ||||||
|  |      */ | ||||||
|  |     numberMax?: number; | ||||||
|  |     numberMin?: number; | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 图标名字 | ||||||
|  |      */ | ||||||
|  |     iconName?: string; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | interface IParameter { | ||||||
|  |     [x: string]: IParamType; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * 参数类型列表 | ||||||
|  |  */ | ||||||
|  | type IParameterOption<P extends IParameter> = { | ||||||
|  |     [X in keyof P]: IParameterOptionItem<P[X]>; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * 参数类型列表映射到参数对象 | ||||||
|  |  */ | ||||||
|  | type IParameterValue<P extends IParameter> = { | ||||||
|  |     [X in keyof P]: IParamValue<P[X]> | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function getDefaultValue<P extends IParameter> (option: IParameterOption<P>): IParameterValue<P> { | ||||||
|  |     let defaultObj = {} as IParameterValue<P>; | ||||||
|  |     for (let key in option) { | ||||||
|  |         let defaultVal = option[key].defaultValue; | ||||||
|  |          | ||||||
|  |         if (defaultVal !== undefined) { | ||||||
|  |             defaultObj[key] = defaultVal; | ||||||
|  |         } else { | ||||||
|  | 
 | ||||||
|  |             switch (option[key].type) { | ||||||
|  |                 case "string": | ||||||
|  |                     defaultObj[key] = "" as any; | ||||||
|  |                     break; | ||||||
|  | 
 | ||||||
|  |                 case "number": | ||||||
|  |                     defaultObj[key] = 0 as any; | ||||||
|  |                     break; | ||||||
|  | 
 | ||||||
|  |                 case "boolean": | ||||||
|  |                     defaultObj[key] = false as any; | ||||||
|  |                     break; | ||||||
|  | 
 | ||||||
|  |                 case "vec": | ||||||
|  |                     defaultObj[key] = [0, 0, 0] as any; | ||||||
|  |                     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; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     return defaultObj; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export { | ||||||
|  |     IParamType, IParamValue, isObjectType, isVectorType, getDefaultValue, | ||||||
|  |     IParameterOptionItem, IParameter, IParameterOption, IParameterValue | ||||||
|  | } | ||||||
| @ -1,4 +1,4 @@ | |||||||
| import { CtrlObject } from "./CtrlObject"; | import { CtrlObject } from "@Model/CtrlObject"; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * 范围 |  * 范围 | ||||||
|  | |||||||
| @ -1,7 +1,7 @@ | |||||||
| import { Component, ReactNode, createRef } from "react"; | import { Component, ReactNode, createRef } from "react"; | ||||||
| import { ClassicRenderer } from "@GLRender/ClassicRenderer"; | import { ClassicRenderer } from "@GLRender/ClassicRenderer"; | ||||||
| import { Entry } from "../Entry/Entry"; |  | ||||||
| import { Model } from "@Model/Model"; | import { Model } from "@Model/Model"; | ||||||
|  | import { Entry } from "../Entry/Entry"; | ||||||
| import "./Laboratory.scss"; | import "./Laboratory.scss"; | ||||||
| 
 | 
 | ||||||
| class Laboratory extends Component { | class Laboratory extends Component { | ||||||
|  | |||||||
| @ -1,16 +1,16 @@ | |||||||
| import { Component, ReactNode } from "react"; | import { Component, ReactNode } from "react"; | ||||||
| import { SettingProvider, Setting } from "@Context/Setting"; | import { SettingProvider, Setting } from "@Context/Setting"; | ||||||
| import { HeaderBar } from "@Component/HeaderBar/HeaderBar"; |  | ||||||
| import { Theme, BackgroundLevel, FontLevel } from "@Component/Theme/Theme"; | import { Theme, BackgroundLevel, FontLevel } from "@Component/Theme/Theme"; | ||||||
| import { Entry } from "../Entry/Entry"; |  | ||||||
| import { StatusProvider, Status } from "@Context/Status"; | import { StatusProvider, Status } from "@Context/Status"; | ||||||
| import { ClassicRenderer } from "@GLRender/ClassicRenderer"; | import { ClassicRenderer } from "@GLRender/ClassicRenderer"; | ||||||
| import { initializeIcons } from '@fluentui/font-icons-mdl2'; | import { initializeIcons } from '@fluentui/font-icons-mdl2'; | ||||||
| import { RootContainer } from "@Component/Container/RootContainer"; | import { RootContainer } from "@Component/Container/RootContainer"; | ||||||
| import { LayoutDirection } from "@Context/Layout"; | import { LayoutDirection } from "@Context/Layout"; | ||||||
| import { CommandBar } from "@Component/CommandBar/CommandBar"; |  | ||||||
| import { Popup } from "@Component/Popup/Popup"; |  | ||||||
| import { AllBehaviors } from "@Behavior/Behavior"; | import { AllBehaviors } from "@Behavior/Behavior"; | ||||||
|  | import { CommandBar } from "@Component/CommandBar/CommandBar"; | ||||||
|  | import { HeaderBar } from "@Component/HeaderBar/HeaderBar"; | ||||||
|  | import { Popup } from "@Component/Popup/Popup"; | ||||||
|  | import { Entry } from "../Entry/Entry"; | ||||||
| import "./SimulatorWeb.scss"; | import "./SimulatorWeb.scss"; | ||||||
| 
 | 
 | ||||||
| initializeIcons("https://img.mrkbear.com/fabric-cdn-prod_20210407.001/"); | initializeIcons("https://img.mrkbear.com/fabric-cdn-prod_20210407.001/"); | ||||||
| @ -63,7 +63,7 @@ class SimulatorWeb extends Component { | |||||||
|             brownian.name = "Brownian"; brownian.color = [200, 80, 250]; |             brownian.name = "Brownian"; brownian.color = [200, 80, 250]; | ||||||
|             let boundary = this.status.model.addBehavior(AllBehaviors[3]); |             let boundary = this.status.model.addBehavior(AllBehaviors[3]); | ||||||
|             boundary.name = "Boundary"; boundary.color = [80, 200, 250]; |             boundary.name = "Boundary"; boundary.color = [80, 200, 250]; | ||||||
|             // boundary.parameter.range = this.status.model.allRangeLabel;
 |             boundary.parameter.range.picker = this.status.model.allRangeLabel; | ||||||
|             group.addBehavior(template); |             group.addBehavior(template); | ||||||
|             group.addBehavior(dynamic); |             group.addBehavior(dynamic); | ||||||
|             group.addBehavior(brownian); |             group.addBehavior(brownian); | ||||||
|  | |||||||
| @ -1,13 +1,13 @@ | |||||||
| import { Component, Fragment, ReactNode} from "react"; | import { Component, ReactNode} from "react"; | ||||||
| import { useSettingWithEvent, IMixinSettingProps } from "@Context/Setting"; | import { useSettingWithEvent, IMixinSettingProps } from "@Context/Setting"; | ||||||
| import { useStatusWithEvent, IMixinStatusProps } from "@Context/Status"; | import { useStatusWithEvent, IMixinStatusProps } from "@Context/Status"; | ||||||
| import { Behavior, IBehaviorParameter, isObjectType, isVectorType } from "@Model/Behavior"; | import { IAnyBehavior } from "@Model/Behavior"; | ||||||
| import { Message } from "@Component/Message/Message"; | import { Message } from "@Input/Message/Message"; | ||||||
| import { AttrInput } from "@Component/AttrInput/AttrInput"; | import { AttrInput } from "@Input/AttrInput/AttrInput"; | ||||||
| import { ColorInput } from "@Component/ColorInput/ColorInput"; | import { ColorInput } from "@Input/ColorInput/ColorInput"; | ||||||
| import { TogglesInput } from "@Component/TogglesInput/TogglesInput"; | import { TogglesInput } from "@Input/TogglesInput/TogglesInput"; | ||||||
| import { ConfirmPopup } from "@Component/ConfirmPopup/ConfirmPopup"; | import { ConfirmPopup } from "@Component/ConfirmPopup/ConfirmPopup"; | ||||||
| import { ObjectPicker } from "@Component/ObjectPicker/ObjectPicker"; | import { Parameter } from "@Input/Parameter/Parameter"; | ||||||
| import "./BehaviorDetails.scss"; | import "./BehaviorDetails.scss"; | ||||||
| 
 | 
 | ||||||
| interface IBehaviorDetailsProps {} | interface IBehaviorDetailsProps {} | ||||||
| @ -16,10 +16,23 @@ interface IBehaviorDetailsProps {} | |||||||
| @useStatusWithEvent("focusBehaviorChange", "behaviorAttrChange") | @useStatusWithEvent("focusBehaviorChange", "behaviorAttrChange") | ||||||
| class BehaviorDetails extends Component<IBehaviorDetailsProps & IMixinStatusProps & IMixinSettingProps> { | class BehaviorDetails extends Component<IBehaviorDetailsProps & IMixinStatusProps & IMixinSettingProps> { | ||||||
| 
 | 
 | ||||||
| 	private renderFrom<T extends IBehaviorParameter> |     private handelDeleteBehavior = (behavior: IAnyBehavior) => { | ||||||
|     (behavior: Behavior<T, Record<string, any>>): ReactNode { |         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(); | ||||||
|  |                 } | ||||||
|  |             }) | ||||||
|  |         } | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|         const allParameterKeys = Object.getOwnPropertyNames(behavior.parameterOption); | 	private renderFrom(behavior: IAnyBehavior): ReactNode { | ||||||
|          |          | ||||||
| 		return <> | 		return <> | ||||||
|          |          | ||||||
| @ -44,145 +57,29 @@ class BehaviorDetails extends Component<IBehaviorDetailsProps & IMixinStatusProp | |||||||
| 				keyI18n="Common.Attr.Key.Delete" red | 				keyI18n="Common.Attr.Key.Delete" red | ||||||
| 				onIconName="delete" offIconName="delete" | 				onIconName="delete" offIconName="delete" | ||||||
| 				valueChange={() => { | 				valueChange={() => { | ||||||
| 					if (this.props.status) { | 					this.handelDeleteBehavior(behavior) | ||||||
|                         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(); |  | ||||||
|                             } |  | ||||||
|                         }) |  | ||||||
|                     } |  | ||||||
| 				}} | 				}} | ||||||
| 			/> | 			/> | ||||||
|              |              | ||||||
|             { |             <Parameter | ||||||
|                 allParameterKeys.length > 0 ? |                 key={behavior.id} | ||||||
|                     <Message |                 option={behavior.parameterOption} | ||||||
|                         isTitle |                 value={behavior.parameter} | ||||||
|                         i18nKey="Panel.Info.Behavior.Details.Behavior.Props" |                 i18n={(option, language) => behavior.getTerms(option.name, language)} | ||||||
|                         options={{ |                 title={"Panel.Info.Behavior.Details.Behavior.Props"} | ||||||
|  |                 titleOption={{ | ||||||
|                     behavior: behavior.getTerms(behavior.behaviorName, this.props.setting?.language) |                     behavior: behavior.getTerms(behavior.behaviorName, this.props.setting?.language) | ||||||
|                 }} |                 }} | ||||||
|                     /> : null |                 change={(key, value) => { | ||||||
|             } |                     this.props.status?.changeBehaviorAttrib( | ||||||
|              |                         behavior.id, key as string, value | ||||||
|             { |                     ); | ||||||
|                 allParameterKeys.map((key) => { |                 }} | ||||||
|                     return this.renderParameter(behavior, key); |             /> | ||||||
|                 }) |  | ||||||
|             } |  | ||||||
| 
 | 
 | ||||||
|         </>; |         </>; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|     private renderParameter<T extends IBehaviorParameter> |  | ||||||
|     (behavior: Behavior<T, Record<string, any>>, key: keyof T): ReactNode { |  | ||||||
|         const type = behavior.parameterOption[key]; |  | ||||||
|         const value = behavior.parameter[key]; |  | ||||||
|         const indexKey = `${behavior.id}-${key}`; |  | ||||||
| 
 |  | ||||||
|         if (type.type === "number") { |  | ||||||
|             return <AttrInput |  | ||||||
|                 keyI18n="Panel.Info.Behavior.Details.Parameter.Key" |  | ||||||
|                 keyI18nOption={{ key: behavior.getTerms(type.name, this.props.setting?.language) }} |  | ||||||
|                 key={indexKey} id={indexKey} isNumber={true} step={type.numberStep} maxLength={type.maxLength} |  | ||||||
|                 max={type.numberMax} min={type.numberMin} |  | ||||||
|                 value={(value as number) ?? 0} |  | ||||||
|                 valueChange={(val) => { |  | ||||||
|                     this.props.status?.changeBehaviorAttrib(behavior.id, key as string, (val as any) / 1); |  | ||||||
|                 }} |  | ||||||
|             /> |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (type.type === "string") { |  | ||||||
|             return <AttrInput |  | ||||||
|                 keyI18n="Panel.Info.Behavior.Details.Parameter.Key" |  | ||||||
|                 keyI18nOption={{ key: behavior.getTerms(type.name, this.props.setting?.language) }} |  | ||||||
|                 key={indexKey} id={indexKey} maxLength={type.maxLength} |  | ||||||
|                 value={(value as string) ?? ""} |  | ||||||
|                 valueChange={(val) => { |  | ||||||
|                     this.props.status?.changeBehaviorAttrib(behavior.id, key as string, val); |  | ||||||
|                 }} |  | ||||||
|             /> |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (type.type === "boolean") { |  | ||||||
|             return <TogglesInput |  | ||||||
|                 keyI18n="Panel.Info.Behavior.Details.Parameter.Key" |  | ||||||
|                 keyI18nOption={{ key: behavior.getTerms(type.name, this.props.setting?.language) }} |  | ||||||
| 				onIconName={type.iconName} key={indexKey} value={(value as boolean) ?? false} |  | ||||||
| 				valueChange={(val) => { |  | ||||||
| 					this.props.status?.changeBehaviorAttrib(behavior.id, key as string, val); |  | ||||||
| 				}} |  | ||||||
| 			/> |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (isObjectType(type.type as any)) { |  | ||||||
|             return <ObjectPicker |  | ||||||
|                 keyI18n="Panel.Info.Behavior.Details.Parameter.Key" |  | ||||||
|                 keyI18nOption={{ key: behavior.getTerms(type.name, this.props.setting?.language) }} |  | ||||||
|                 type={type.type} value={(value as any).picker} |  | ||||||
|                 valueChange={(obj) => { |  | ||||||
|                     (value as any).picker = obj; |  | ||||||
|                     this.props.status?.changeBehaviorAttrib(behavior.id, key as string, value); |  | ||||||
|                 }} |  | ||||||
|                 cleanValue={() => { |  | ||||||
|                     (value as any).picker = undefined; |  | ||||||
|                     this.props.status?.changeBehaviorAttrib(behavior.id, key as string, value); |  | ||||||
|                 }} |  | ||||||
|             /> |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (isVectorType(type.type as any)) { |  | ||||||
|             return <Fragment key={indexKey}> |  | ||||||
|                  |  | ||||||
|                 <AttrInput |  | ||||||
|                     keyI18n="Panel.Info.Behavior.Details.Parameter.Key.Vec.X" |  | ||||||
|                     keyI18nOption={{ key: behavior.getTerms(type.name, this.props.setting?.language) }} |  | ||||||
|                     key={`${indexKey}-X`} id={indexKey} isNumber={true} step={type.numberStep} maxLength={type.maxLength} |  | ||||||
|                     max={type.numberMax} min={type.numberMin} |  | ||||||
|                     value={(value as number[])[0] ?? 0} |  | ||||||
|                     valueChange={(val) => { |  | ||||||
|                         (value as number[])[0] = (val as any) / 1; |  | ||||||
|                         this.props.status?.changeBehaviorAttrib(behavior.id, key as string, value); |  | ||||||
|                     }} |  | ||||||
|                 /> |  | ||||||
| 
 |  | ||||||
|                 <AttrInput |  | ||||||
|                     keyI18n="Panel.Info.Behavior.Details.Parameter.Key.Vec.Y" |  | ||||||
|                     keyI18nOption={{ key: behavior.getTerms(type.name, this.props.setting?.language) }} |  | ||||||
|                     key={`${indexKey}-Y`} id={indexKey} isNumber={true} step={type.numberStep} maxLength={type.maxLength} |  | ||||||
|                     max={type.numberMax} min={type.numberMin} |  | ||||||
|                     value={(value as number[])[1] ?? 0} |  | ||||||
|                     valueChange={(val) => { |  | ||||||
|                         (value as number[])[1] = (val as any) / 1; |  | ||||||
|                         this.props.status?.changeBehaviorAttrib(behavior.id, key as string, value); |  | ||||||
|                     }} |  | ||||||
|                 /> |  | ||||||
| 
 |  | ||||||
|                 <AttrInput |  | ||||||
|                     keyI18n="Panel.Info.Behavior.Details.Parameter.Key.Vec.Z" |  | ||||||
|                     keyI18nOption={{ key: behavior.getTerms(type.name, this.props.setting?.language) }} |  | ||||||
|                     key={`${indexKey}-Z`} id={indexKey} isNumber={true} step={type.numberStep} maxLength={type.maxLength} |  | ||||||
|                     max={type.numberMax} min={type.numberMin} |  | ||||||
|                     value={(value as number[])[2] ?? 0} |  | ||||||
|                     valueChange={(val) => { |  | ||||||
|                         (value as number[])[2] = (val as any) / 1; |  | ||||||
|                         this.props.status?.changeBehaviorAttrib(behavior.id, key as string, value); |  | ||||||
|                     }} |  | ||||||
|                 /> |  | ||||||
| 
 |  | ||||||
|             </Fragment> |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return <Fragment key={indexKey}/> |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
| 	public render(): ReactNode { | 	public render(): ReactNode { | ||||||
| 		if (this.props.status && this.props.status.focusBehavior) { | 		if (this.props.status && this.props.status.focusBehavior) { | ||||||
|             return this.renderFrom(this.props.status.focusBehavior); |             return this.renderFrom(this.props.status.focusBehavior); | ||||||
|  | |||||||
| @ -1,11 +1,11 @@ | |||||||
| import { BehaviorList as BehaviorListComponent } from "@Component/BehaviorList/BehaviorList"; |  | ||||||
| import { Component } from "react"; | import { Component } from "react"; | ||||||
|  | import { BehaviorList as BehaviorListComponent } from "@Component/BehaviorList/BehaviorList"; | ||||||
| import { useStatusWithEvent, IMixinStatusProps } from "@Context/Status"; | import { useStatusWithEvent, IMixinStatusProps } from "@Context/Status"; | ||||||
| import { useSetting, IMixinSettingProps } from "@Context/Setting"; | import { useSetting, IMixinSettingProps } from "@Context/Setting"; | ||||||
| import { Behavior } from "@Model/Behavior"; |  | ||||||
| import { Message } from "@Component/Message/Message"; |  | ||||||
| import { ConfirmPopup } from "@Component/ConfirmPopup/ConfirmPopup"; | import { ConfirmPopup } from "@Component/ConfirmPopup/ConfirmPopup"; | ||||||
| import { BehaviorPopup } from "@Component/BehaviorPopup/BehaviorPopup"; | import { BehaviorPopup } from "@Component/BehaviorPopup/BehaviorPopup"; | ||||||
|  | import { Behavior } from "@Model/Behavior"; | ||||||
|  | import { Message } from "@Input/Message/Message"; | ||||||
| import "./BehaviorList.scss"; | import "./BehaviorList.scss"; | ||||||
| 
 | 
 | ||||||
| interface IBehaviorListProps { | interface IBehaviorListProps { | ||||||
|  | |||||||
| @ -1,18 +1,18 @@ | |||||||
| import { Component, ReactNode } from "react"; | import { Component, ReactNode } from "react"; | ||||||
| import { AttrInput } from "@Component/AttrInput/AttrInput"; | import { AttrInput } from "@Input/AttrInput/AttrInput"; | ||||||
| import { useStatusWithEvent, IMixinStatusProps } from "@Context/Status"; | import { useStatusWithEvent, IMixinStatusProps } from "@Context/Status"; | ||||||
| import { useSetting, IMixinSettingProps } from "@Context/Setting"; | import { useSetting, IMixinSettingProps } from "@Context/Setting"; | ||||||
| import { Message } from "@Component/Message/Message"; | import { ComboInput, IDisplayItem } from "@Input/ComboInput/ComboInput"; | ||||||
|  | import { Message } from "@Input/Message/Message"; | ||||||
| import { ObjectID } from "@Model/Renderer"; | import { ObjectID } from "@Model/Renderer"; | ||||||
| import { ColorInput } from "@Component/ColorInput/ColorInput"; | import { ColorInput } from "@Input/ColorInput/ColorInput"; | ||||||
| import { TogglesInput } from "@Component/TogglesInput/TogglesInput"; | import { TogglesInput } from "@Input/TogglesInput/TogglesInput"; | ||||||
| import { LabelPicker } from "@Component/LabelPicker/LabelPicker"; | import { LabelPicker } from "@Input/LabelPicker/LabelPicker"; | ||||||
| import { Group, GenMod } from "@Model/Group"; | import { Group, GenMod } from "@Model/Group"; | ||||||
| import { AllI18nKeys } from "@Component/Localization/Localization"; | import { AllI18nKeys } from "@Component/Localization/Localization"; | ||||||
| import { ComboInput, IDisplayItem } from "@Component/ComboInput/ComboInput"; | import { ObjectPicker } from "@Input/ObjectPicker/ObjectPicker"; | ||||||
| import { ObjectPicker } from "@Component/ObjectPicker/ObjectPicker"; |  | ||||||
| import { ConfirmPopup } from "@Component/ConfirmPopup/ConfirmPopup"; | import { ConfirmPopup } from "@Component/ConfirmPopup/ConfirmPopup"; | ||||||
| import { BehaviorPicker } from "@Component/BehaviorPicker/BehaviorPicker"; | import { BehaviorPicker } from "@Input/BehaviorPicker/BehaviorPicker"; | ||||||
| import "./GroupDetails.scss"; | import "./GroupDetails.scss"; | ||||||
| 
 | 
 | ||||||
| interface IGroupDetailsProps {} | interface IGroupDetailsProps {} | ||||||
|  | |||||||
| @ -1,11 +1,11 @@ | |||||||
| import { Component, ReactNode } from "react"; | import { Component, ReactNode } from "react"; | ||||||
| import { AttrInput } from "@Component/AttrInput/AttrInput"; |  | ||||||
| import { useStatusWithEvent, IMixinStatusProps } from "@Context/Status"; | import { useStatusWithEvent, IMixinStatusProps } from "@Context/Status"; | ||||||
| import { Message } from "@Component/Message/Message"; | import { TogglesInput } from "@Input/TogglesInput/TogglesInput"; | ||||||
| import { ColorInput } from "@Component/ColorInput/ColorInput"; |  | ||||||
| import { Label } from "@Model/Label"; |  | ||||||
| import { TogglesInput } from "@Component/TogglesInput/TogglesInput"; |  | ||||||
| import { ConfirmPopup } from "@Component/ConfirmPopup/ConfirmPopup"; | import { ConfirmPopup } from "@Component/ConfirmPopup/ConfirmPopup"; | ||||||
|  | import { ColorInput } from "@Input/ColorInput/ColorInput"; | ||||||
|  | import { AttrInput } from "@Input/AttrInput/AttrInput"; | ||||||
|  | import { Message } from "@Input/Message/Message"; | ||||||
|  | import { Label } from "@Model/Label"; | ||||||
| import "./LabelDetails.scss"; | import "./LabelDetails.scss"; | ||||||
| 
 | 
 | ||||||
| @useStatusWithEvent("focusLabelChange", "labelAttrChange", "labelChange") | @useStatusWithEvent("focusLabelChange", "labelAttrChange", "labelChange") | ||||||
|  | |||||||
| @ -1,10 +1,10 @@ | |||||||
| import { LabelList as LabelListComponent } from "@Component/LabelList/LabelList"; |  | ||||||
| import { Component } from "react"; | import { Component } from "react"; | ||||||
|  | import { LabelList as LabelListComponent } from "@Component/LabelList/LabelList"; | ||||||
| import { useStatusWithEvent, IMixinStatusProps } from "@Context/Status"; | import { useStatusWithEvent, IMixinStatusProps } from "@Context/Status"; | ||||||
| import { useSetting, IMixinSettingProps } from "@Context/Setting"; | import { useSetting, IMixinSettingProps } from "@Context/Setting"; | ||||||
| import { Label } from "@Model/Label"; |  | ||||||
| import { Message } from "@Component/Message/Message"; |  | ||||||
| import { ConfirmPopup } from "@Component/ConfirmPopup/ConfirmPopup"; | import { ConfirmPopup } from "@Component/ConfirmPopup/ConfirmPopup"; | ||||||
|  | import { Message } from "@Input/Message/Message"; | ||||||
|  | import { Label } from "@Model/Label"; | ||||||
| import "./LabelList.scss"; | import "./LabelList.scss"; | ||||||
| 
 | 
 | ||||||
| interface ILabelListProps { | interface ILabelListProps { | ||||||
|  | |||||||
| @ -1,9 +1,9 @@ | |||||||
| import { BackgroundLevel, FontLevel, Theme } from "@Component/Theme/Theme"; |  | ||||||
| import { useStatus, IMixinStatusProps } from "../../Context/Status"; |  | ||||||
| import { ConfirmPopup } from "@Component/ConfirmPopup/ConfirmPopup"; |  | ||||||
| import { Icon } from "@fluentui/react"; |  | ||||||
| import { Component, ReactNode } from "react"; | import { Component, ReactNode } from "react"; | ||||||
|  | import { BackgroundLevel, FontLevel, Theme } from "@Component/Theme/Theme"; | ||||||
|  | import { useStatus, IMixinStatusProps } from "@Context/Status"; | ||||||
|  | import { ConfirmPopup } from "@Component/ConfirmPopup/ConfirmPopup"; | ||||||
| import { ObjectID } from "@Model/Renderer"; | import { ObjectID } from "@Model/Renderer"; | ||||||
|  | import { Icon } from "@fluentui/react"; | ||||||
| import "./ObjectList.scss"; | import "./ObjectList.scss"; | ||||||
| 
 | 
 | ||||||
| @useStatus | @useStatus | ||||||
|  | |||||||
| @ -1,8 +1,8 @@ | |||||||
| import { Component, ReactNode } from "react"; | import { Component, ReactNode } from "react"; | ||||||
| import { DetailsList } from "@Component/DetailsList/DetailsList"; |  | ||||||
| import { useStatusWithEvent, IMixinStatusProps } from "@Context/Status"; | import { useStatusWithEvent, IMixinStatusProps } from "@Context/Status"; | ||||||
| import { useSetting, IMixinSettingProps } from "@Context/Setting"; | import { useSetting, IMixinSettingProps } from "@Context/Setting"; | ||||||
| import { Localization } from "@Component/Localization/Localization"; | import { Localization } from "@Component/Localization/Localization"; | ||||||
|  | import { DetailsList } from "@Component/DetailsList/DetailsList"; | ||||||
| import { ObjectID } from "@Model/Renderer"; | import { ObjectID } from "@Model/Renderer"; | ||||||
| import { Icon } from "@fluentui/react"; | import { Icon } from "@fluentui/react"; | ||||||
| import "./ObjectList.scss"; | import "./ObjectList.scss"; | ||||||
|  | |||||||
| @ -1,15 +1,15 @@ | |||||||
| import { ReactNode, Component, FunctionComponent } from "react"; | import { ReactNode, Component, FunctionComponent } from "react"; | ||||||
| import { Theme } from "@Component/Theme/Theme"; | import { Theme } from "@Component/Theme/Theme"; | ||||||
| import { Message } from "@Component/Message/Message"; | import { Message } from "@Input/Message/Message"; | ||||||
| import { RenderView } from "./RenderView/RenderView"; | import { RenderView } from "@Panel/RenderView/RenderView"; | ||||||
| import { ObjectList } from "./ObjectList/ObjectList"; | import { ObjectList } from "@Panel/ObjectList/ObjectList"; | ||||||
| import { ObjectCommand } from "./ObjectList/ObjectCommand"; | import { ObjectCommand } from "@Panel/ObjectList/ObjectCommand"; | ||||||
| import { RangeDetails } from "./RangeDetails/RangeDetails"; | import { RangeDetails } from "@Panel/RangeDetails/RangeDetails"; | ||||||
| import { LabelList } from "./LabelList/LabelList"; | import { LabelList } from "@Panel/LabelList/LabelList"; | ||||||
| import { LabelDetails } from "./LabelDetails/LabelDetails"; | import { LabelDetails } from "@Panel/LabelDetails/LabelDetails"; | ||||||
| import { GroupDetails } from "./GroupDetails/GroupDetails"; | import { GroupDetails } from "@Panel/GroupDetails/GroupDetails"; | ||||||
| import { BehaviorList } from "./BehaviorList/BehaviorList"; | import { BehaviorList } from "@Panel/BehaviorList/BehaviorList"; | ||||||
| import { BehaviorDetails } from "./BehaviorDetails/BehaviorDetails"; | import { BehaviorDetails } from "@Panel/BehaviorDetails/BehaviorDetails"; | ||||||
| 
 | 
 | ||||||
| interface IPanelInfo { | interface IPanelInfo { | ||||||
| 	nameKey: string; | 	nameKey: string; | ||||||
|  | |||||||
| @ -1,12 +1,12 @@ | |||||||
| import { Component, ReactNode } from "react"; | import { Component, ReactNode } from "react"; | ||||||
| import { AttrInput } from "@Component/AttrInput/AttrInput"; | import { useStatusWithEvent, IMixinStatusProps } from "@Context/Status"; | ||||||
| import { useStatusWithEvent, IMixinStatusProps, Status } from "@Context/Status"; | import { AttrInput } from "@Input/AttrInput/AttrInput"; | ||||||
| import { Message } from "@Component/Message/Message"; | import { Message } from "@Input/Message/Message"; | ||||||
| import { Range } from "@Model/Range"; | import { Range } from "@Model/Range"; | ||||||
| import { ObjectID } from "@Model/Renderer"; | import { ObjectID } from "@Model/Renderer"; | ||||||
| import { ColorInput } from "@Component/ColorInput/ColorInput"; | import { ColorInput } from "@Input/ColorInput/ColorInput"; | ||||||
| import { TogglesInput } from "@Component/TogglesInput/TogglesInput"; | import { TogglesInput } from "@Input/TogglesInput/TogglesInput"; | ||||||
| import { LabelPicker } from "@Component/LabelPicker/LabelPicker"; | import { LabelPicker } from "@Input/LabelPicker/LabelPicker"; | ||||||
| import { ConfirmPopup } from "@Component/ConfirmPopup/ConfirmPopup"; | import { ConfirmPopup } from "@Component/ConfirmPopup/ConfirmPopup"; | ||||||
| import "./RangeDetails.scss"; | import "./RangeDetails.scss"; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -32,6 +32,9 @@ | |||||||
|             "@Component/*": [ |             "@Component/*": [ | ||||||
|                 "./source/Component/*" |                 "./source/Component/*" | ||||||
|             ], |             ], | ||||||
|  |             "@Input/*": [ | ||||||
|  |                 "./source/Input/*" | ||||||
|  |             ], | ||||||
|             "@Localization/*": [ |             "@Localization/*": [ | ||||||
|                 "./source/Localization/*" |                 "./source/Localization/*" | ||||||
|             ], |             ], | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user