diff --git a/source/Context/Popups.ts b/source/Context/Popups.ts index e5e4cd6..5ee7767 100644 --- a/source/Context/Popups.ts +++ b/source/Context/Popups.ts @@ -1,7 +1,7 @@ import { ReactNode, createElement } from "react"; import { Emitter } from "@Model/Emitter"; import { Localization } from "@Component/Localization/Localization"; -import { IAnyObject } from "@Model/Renderer"; +import { IAnyObject } from "@Model/Model"; enum ResizeDragDirection { top = 1, diff --git a/source/GLRender/BasicGroup.ts b/source/GLRender/BasicGroup.ts index 4c79403..15c4af2 100644 --- a/source/GLRender/BasicGroup.ts +++ b/source/GLRender/BasicGroup.ts @@ -44,6 +44,11 @@ class BasicGroup extends DisplayObject { */ public color = [1, 1, 1]; + /** + * 形状 + */ + public shape: number = 0; + /** * 绘制立方体 */ @@ -66,6 +71,9 @@ class BasicGroup extends DisplayObject { // 半径传递 this.shader.radius(this.size); + // 形状传递 + this.shader.shape(this.shape); + // 指定颜色 this.shader.color(this.color); diff --git a/source/GLRender/BasicRenderer.ts b/source/GLRender/BasicRenderer.ts index 661c6cf..bd36370 100644 --- a/source/GLRender/BasicRenderer.ts +++ b/source/GLRender/BasicRenderer.ts @@ -1,4 +1,4 @@ -import { AbstractRenderer, IRendererParam, IAnyObject } from "@Model/Renderer"; +import { AbstractRenderer, IRendererParam } from "@Model/Renderer"; import { EventType } from "@Model/Emitter"; import { GLCanvas, GLCanvasOption } from "./GLCanvas"; import { GLContext } from "./GLContext"; @@ -16,19 +16,13 @@ type IRendererParams = IRendererOwnParams & GLCanvasOption; abstract class BasicRenderer< P extends IRendererParam = {}, - M extends IAnyObject = {}, E extends Record = {} -> extends AbstractRenderer { +> extends AbstractRenderer { public get dom() { return this.canvas.dom } - /** - * 渲染器参数 - */ - public param: Partial = {}; - /** * 使用的画布 */ @@ -44,19 +38,16 @@ abstract class BasicRenderer< */ protected clock: Clock; - public constructor(param: Partial = {}) { + public constructor() { super(); - - // 初始化参数 - this.param = { - autoResize: param.autoResize ?? true, - mouseEvent: param.autoResize ?? true, - eventLog: param.eventLog ?? false, - className: param.className ?? "" - } as M & IRendererParams; // 实例化画布对象 - this.canvas = new GLCanvas(param.canvas, this.param); + this.canvas = new GLCanvas(undefined, { + autoResize: true, + mouseEvent: true, + eventLog: false, + className: "canvas" + }); // 实例化摄像机 this.camera = new Camera(this.canvas); diff --git a/source/GLRender/ClassicRenderer.ts b/source/GLRender/ClassicRenderer.ts index 29dc2b7..10e5fbe 100644 --- a/source/GLRender/ClassicRenderer.ts +++ b/source/GLRender/ClassicRenderer.ts @@ -1,27 +1,49 @@ -import { ObjectID, ObjectData, ICommonParam } from "@Model/Renderer"; +import { ObjectData } from "@Model/Renderer"; +import { ObjectID } from "@Model/Model"; +import { IParameterValue, getDefaultValue } from "@Model/Parameter"; import { BasicRenderer } from "./BasicRenderer"; import { BasicsShader } from "./BasicShader"; import { Axis } from "./Axis"; import { BasicCube } from "./BasicCube"; import { GroupShader } from "./GroupShader"; import { BasicGroup } from "./BasicGroup"; -import DisplayObject from "./DisplayObject"; - -interface IClassicRendererParams { - point: { - size: number; - } - cube: { - radius: number[]; - } -} +import { DisplayObject } from "./DisplayObject"; enum MouseMod { Drag = 1, click = 2 } -class ClassicRenderer extends BasicRenderer<{}, IClassicRendererParams> { +type IClassicRendererParameter = { + renderer: {}; + points: { + color: "color", + size: "number", + shape: "option" + }; + cube: { + color: "color" + }; +} + +class ClassicRenderer extends BasicRenderer { + + public override rendererParameterOption = {}; + public override pointsParameterOption = { + color: { type: "color", name: "", defaultValue: [0, 0, 0] }, + size: { type: "number", name: "Common.Attr.Key.Size", defaultValue: 60, numberStep: 10, numberMin: 0 }, + shape: { type: "option", name: "Common.Render.Attr.Key.Display.Shape", defaultValue: "0", allOption: [ + { key: "0", name: "Common.Render.Attr.Key.Display.Shape.Square" }, + { key: "1", name: "Common.Render.Attr.Key.Display.Shape.Hollow.Square" }, + { key: "2", name: "Common.Render.Attr.Key.Display.Shape.Hollow.Plus" }, + { key: "3", name: "Common.Render.Attr.Key.Display.Shape.Hollow.Reduce" }, + { key: "4", name: "Common.Render.Attr.Key.Display.Shape.Hollow.Cross" }, + { key: "5", name: "Common.Render.Attr.Key.Display.Shape.Hollow.Checkerboard" } + ]} + }; + public override cubeParameterOption = { + color: { type: "color", name: "", defaultValue: [0, 0, 0] }, + }; private basicShader: BasicsShader = undefined as any; private axisObject: Axis = undefined as any; @@ -51,6 +73,8 @@ class ClassicRenderer extends BasicRenderer<{}, IClassicRendererParams> { } public onLoad(): this { + + this.rendererParameter = getDefaultValue(this.rendererParameterOption); // 自动调节分辨率 this.autoResize(); @@ -187,7 +211,7 @@ class ClassicRenderer extends BasicRenderer<{}, IClassicRendererParams> { points( id: ObjectID, position?: ObjectData, - param?: Readonly> + param?: Readonly> ): this { let object = this.objectPool.get(id); let group: BasicGroup; @@ -229,14 +253,19 @@ class ClassicRenderer extends BasicRenderer<{}, IClassicRendererParams> { if (param.size) { group.size = param.size; } + + // 半径数据 + if (param.shape) { + group.shape = parseInt(param.shape); + } } return this; } cube( - id: ObjectID, position?: ObjectData, - param?: Readonly> + id: ObjectID, position?: ObjectData, radius?: ObjectData, + param?: Readonly> ): this { let object = this.objectPool.get(id); let cube: BasicCube; @@ -250,6 +279,13 @@ class ClassicRenderer extends BasicRenderer<{}, IClassicRendererParams> { cube.position[1] = position[1] ?? cube.position[1]; cube.position[2] = position[2] ?? cube.position[2]; } + + if (radius) { + cube.r[0] = radius[0] ?? cube.r[0]; + cube.r[1] = radius[1] ?? cube.r[1]; + cube.r[2] = radius[2] ?? cube.r[2]; + } + } else { throw new Error("Renderer: Use duplicate ObjectID when drawing different types of objects"); } @@ -263,6 +299,12 @@ class ClassicRenderer extends BasicRenderer<{}, IClassicRendererParams> { cube.position[2] = position[2] ?? cube.position[2]; } + if (radius) { + cube.r[0] = radius[0] ?? cube.r[0]; + cube.r[1] = radius[1] ?? cube.r[1]; + cube.r[2] = radius[2] ?? cube.r[2]; + } + this.objectPool.set(id, cube); console.log(`Renderer: Create new cube object with id ${id}`); } @@ -271,21 +313,11 @@ class ClassicRenderer extends BasicRenderer<{}, IClassicRendererParams> { cube.isDraw = true; // 参数传递 - if (param) { + if (param && param.color) { - // 颜色数据 - if (param.color) { - cube.color[0] = param.color[0] ?? cube.color[0] - cube.color[1] = param.color[1] ?? cube.color[1] - cube.color[2] = param.color[2] ?? cube.color[2] - } - - // 半径数据 - if (param.radius) { - cube.r[0] = param.radius[0] ?? cube.r[0]; - cube.r[1] = param.radius[1] ?? cube.r[1]; - cube.r[2] = param.radius[2] ?? cube.r[2]; - } + cube.color[0] = param.color[0] ?? cube.color[0]; + cube.color[1] = param.color[1] ?? cube.color[1]; + cube.color[2] = param.color[2] ?? cube.color[2]; } return this; diff --git a/source/GLRender/GroupShader.ts b/source/GLRender/GroupShader.ts index e422863..ee4b05f 100644 --- a/source/GLRender/GroupShader.ts +++ b/source/GLRender/GroupShader.ts @@ -10,6 +10,7 @@ interface IGroupShaderAttribute { interface IGroupShaderUniform { uRadius: number, + uShape: number, uMvp: ObjectData, uColor: ObjectData, uFogColor: ObjectData, @@ -50,10 +51,42 @@ class GroupShader extends GLShader{ uniform vec3 uColor; uniform vec3 uFogColor; + uniform int uShape; varying float vFogPower; void main(){ + + float dist = distance(gl_PointCoord, vec2(0.5, 0.5)); + vec2 normalPos = (gl_PointCoord - vec2(0.5, 0.5)) * 2.; + + if ( uShape == 1 && abs(normalPos.x) < .6 && abs(normalPos.y) < .6) { + discard; + } + + if ( uShape == 2 && abs(normalPos.x) > .3 && abs(normalPos.y) > .3) { + discard; + } + + if ( uShape == 3 && abs(normalPos.y) > .3) { + discard; + } + + if ( uShape == 4 && + (abs(normalPos.x) < .4 || abs(normalPos.y) < .4) && + (abs(normalPos.x) > .4 || abs(normalPos.y) > .4) + ) { + discard; + } + + if ( uShape == 5 && + (abs(normalPos.x) < .75 && abs(normalPos.y) < .75) && + (abs(normalPos.x) < .28 || abs(normalPos.y) < .28) && + (abs(normalPos.x) > .28 || abs(normalPos.y) > .28) + ) { + discard; + } + gl_FragColor = vec4(mix(uColor, uFogColor, vFogPower), 1.); } `; @@ -111,4 +144,13 @@ class GroupShader extends GLShader{ this.uniformLocate("uFogDensity"), rgb ) } + + /** + * 形状 + */ + public shape(shape: number) { + this.gl.uniform1i( + this.uniformLocate("uShape"), shape + ) + } } \ No newline at end of file diff --git a/source/Input/AttrInput/AttrInput.tsx b/source/Input/AttrInput/AttrInput.tsx index 575f93c..26f0853 100644 --- a/source/Input/AttrInput/AttrInput.tsx +++ b/source/Input/AttrInput/AttrInput.tsx @@ -1,7 +1,7 @@ import { Component, ReactNode } from "react"; import { Icon } from "@fluentui/react"; import { AllI18nKeys } from "@Component/Localization/Localization"; -import { ObjectID } from "@Model/Renderer"; +import { ObjectID } from "@Model/Model"; import { TextField, ITextFieldProps } from "@Input/TextField/TextField"; import "./AttrInput.scss"; diff --git a/source/Input/Parameter/Parameter.tsx b/source/Input/Parameter/Parameter.tsx index deb6c4b..23bd4ab 100644 --- a/source/Input/Parameter/Parameter.tsx +++ b/source/Input/Parameter/Parameter.tsx @@ -1,7 +1,7 @@ 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 { ObjectID } from "@Model/Model"; import { TogglesInput } from "@Input/TogglesInput/TogglesInput"; import { ObjectPicker } from "@Input/ObjectPicker/ObjectPicker"; import { AllI18nKeys, I18N } from "@Component/Localization/Localization"; @@ -10,7 +10,7 @@ import { ColorInput } from "@Input/ColorInput/ColorInput"; import { ComboInput, IDisplayItem } from "@Input/ComboInput/ComboInput"; import { IParameter, IParameterOption, IParameterOptionItem, - IParameterValue, IParamValue, isObjectType, isVectorType + IParameterValue, IParamValue, isObjectType } from "@Model/Parameter"; import "./Parameter.scss"; @@ -20,6 +20,7 @@ interface IParameterProps

{ key: ObjectID; change: (key: K, val: IParamValue) => any; i18n?: (key: string, language: Language) => string; + renderKey?: Array; title?: AllI18nKeys; titleOption?: Record; isFirst?: boolean; @@ -249,12 +250,18 @@ class Parameter

extends Component & IMi } public render(): ReactNode { - const allOptionKeys: Array = Object.getOwnPropertyNames(this.props.option); + let allOptionKeys: Array; + if (this.props.renderKey) { + allOptionKeys = this.props.renderKey; + } else { + allOptionKeys = Object.getOwnPropertyNames(this.props.option); + } + return <> { - allOptionKeys.length <= 0 && this.props.title ? + allOptionKeys.length > 0 && this.props.title ? ; + type ModelEvent = { labelChange: Label[]; objectChange: CtrlObject[]; @@ -352,17 +362,12 @@ class Model extends Emitter { // 渲染 for (let i = 0; i < this.objectPool.length; i++) { let object = this.objectPool[i]; + object.renderParameter.color = object.color; if (object.display && object instanceof Group) { - this.renderer.points(object.id, object.exportPositionData(), { - color: object.color, - size: object.size - } as any); + this.renderer.points(object.id, object.exportPositionData(), object.renderParameter); } if (object.display && object instanceof Range) { - this.renderer.cube(object.id, object.position, { - color: object.color, - radius: object.radius - } as any); + this.renderer.cube(object.id, object.position, object.radius, object.renderParameter); } } } @@ -376,5 +381,6 @@ export { EventMixin, Model, CtrlObject, - ObjectID + ObjectID, + IAnyObject } \ No newline at end of file diff --git a/source/Model/Range.ts b/source/Model/Range.ts index f6a0191..197b30c 100644 --- a/source/Model/Range.ts +++ b/source/Model/Range.ts @@ -1,4 +1,6 @@ import { CtrlObject } from "@Model/CtrlObject"; +import { Model, ObjectID } from "@Model/Model"; +import { getDefaultValue } from "@Model/Parameter"; /** * 范围 @@ -15,6 +17,15 @@ class Range extends CtrlObject { */ public radius: number[] = [1, 1, 1]; + public constructor(model: Model, id: ObjectID) { + + super(model, id); + + if (model.renderer) { + this.renderParameter = getDefaultValue(model.renderer.cubeParameterOption); + } + } + } export default Range; diff --git a/source/Model/Renderer.ts b/source/Model/Renderer.ts index 2c9ee64..00f491b 100644 --- a/source/Model/Renderer.ts +++ b/source/Model/Renderer.ts @@ -1,24 +1,31 @@ import { Emitter, EventType } from "@Model/Emitter"; +import { IAnyObject, ObjectID } from "@Model/Model"; +import { IParameter, IParameterOption, IParameterValue } from "@Model/Parameter"; /** - * 任意类型对象 + * 默认类型 */ -type IAnyObject = Record; +type IDefaultType = T extends undefined ? D : T; /** * 渲染器参数 */ interface IRendererParam { + /** + * 渲染器参数 + */ + renderer?: IParameter; + /** * 绘制点需要的参数 */ - points?: IAnyObject + points?: IParameter; /** * 绘制立方体需要的参数 */ - cube?: IAnyObject + cube?: IParameter; } /** @@ -32,22 +39,15 @@ interface ICommonParam { color?: ObjectData; } -/** - * 对象标识符 - */ -type ObjectID = string; + /** * 接收的数据类型 */ type ObjectData = Array | Float32Array; -interface IRendererConstructor< - M extends IAnyObject = {} -> { - new (canvas: HTMLCanvasElement, param?: M): AbstractRenderer< - IRendererParam, IAnyObject, AbstractRendererEvent - > +interface IRendererConstructor { + new (): AbstractRenderer } type AbstractRendererEvent = { @@ -63,7 +63,6 @@ type AbstractRendererEvent = { */ abstract class AbstractRenderer< P extends IRendererParam = {}, - M extends IAnyObject = {}, E extends AbstractRendererEvent = {loop: number} > extends Emitter { @@ -72,28 +71,17 @@ abstract class AbstractRenderer< /** * 渲染器参数 */ - abstract param: Partial; + public rendererParameterOption: IParameterOption> = {} as any; + public pointsParameterOption: IParameterOption> = {} as any; + public cubeParameterOption: IParameterOption> = {} as any; /** - * 类型断言 + * 渲染器参数 */ - get isRenderer() { - return true; - } + public rendererParameter: IParameterValue> = {} as any; /** - * 断言对象是否是渲染器 - */ - public static isRenderer(render: any): render is AbstractRenderer { - if (render instanceof Object) { - return !!(render as AbstractRenderer).isRenderer; - } else { - return false; - } - }; - - /** - * @function start + * @function clean * 开始一次数据更新 \ * 此函数将清除固定对象的绘制状态 \ * 在每次数据更新前调用 \ @@ -110,7 +98,9 @@ abstract class AbstractRenderer< * @param id 使用的标识符 * @param position 做标集合 */ - abstract points(id: ObjectID, position?: ObjectData, param?: Readonly): this; + abstract points(id: ObjectID, position?: ObjectData, param?: + Readonly>> + ): this; /** * @function cube 绘制立方体 @@ -120,12 +110,13 @@ abstract class AbstractRenderer< * * 注意: 这里的半径指的是立方体重心与立方体任意一面几何中心的距离 */ - abstract cube(id: ObjectID, position?: ObjectData, param?: Readonly): this; + abstract cube(id: ObjectID, position?: ObjectData, radius?: ObjectData, param?: + Readonly>> + ): this; } export default AbstractRenderer; export { - AbstractRenderer, ObjectID, IAnyObject, - ICommonParam, IRendererParam, + AbstractRenderer, ICommonParam, IRendererParam, ObjectData, IRendererConstructor }; \ No newline at end of file diff --git a/source/Page/Laboratory/Laboratory.tsx b/source/Page/Laboratory/Laboratory.tsx index e3eeb43..8415ae6 100644 --- a/source/Page/Laboratory/Laboratory.tsx +++ b/source/Page/Laboratory/Laboratory.tsx @@ -21,7 +21,7 @@ class Laboratory extends Component { throw new Error("Laboratory: 重复引用 canvas 节点"); } - const renderer = new ClassicRenderer({ className: "canvas" }).onLoad(); + const renderer = new ClassicRenderer().onLoad(); this.canvasContRef.current.appendChild(renderer.canvas.dom); let model = new Model().bindRenderer(renderer); @@ -39,22 +39,24 @@ class Laboratory extends Component { // 测试渲染器 if (false) { - renderer.points("0"); - renderer.points("1", new Array(100 * 3).fill(0).map(() => (Math.random() - .5) * 2)); - renderer.points("2", new Array(100 * 3).fill(0).map(() => (Math.random() - .5) * 2), { - size: 100, - color: [1, 0, 1] - }); - renderer.points("3", new Array(100 * 3).fill(0).map(() => (Math.random() - .5) * 2), { - size: 80, - color: [0, 1, 1] - }); - renderer.points("2"); - renderer.cube("4"); - renderer.cube("5", new Array(3).fill(0).map(() => (Math.random() - .5) * 2), { - radius: new Array(3).fill(0).map(() => Math.random() * 1.2), - color: [1, 1, 0] - }) + // renderer.points("0"); + // renderer.points("1", new Array(100 * 3).fill(0).map(() => (Math.random() - .5) * 2)); + // renderer.points("2", new Array(100 * 3).fill(0).map(() => (Math.random() - .5) * 2), { + // size: 100, + // color: [1, 0, 1] + // }); + // renderer.points("3", new Array(100 * 3).fill(0).map(() => (Math.random() - .5) * 2), { + // size: 80, + // color: [0, 1, 1] + // }); + // renderer.points("2"); + // renderer.cube("4"); + // renderer.cube("5", + // new Array(3).fill(0).map(() => (Math.random() - .5) * 2), + // new Array(3).fill(0).map(() => Math.random() * 1.2), { + // color: [1, 1, 0] + // } + // ) } (window as any).renderer = renderer; diff --git a/source/Page/SimulatorWeb/SimulatorWeb.tsx b/source/Page/SimulatorWeb/SimulatorWeb.tsx index 9e67110..2b53cfb 100644 --- a/source/Page/SimulatorWeb/SimulatorWeb.tsx +++ b/source/Page/SimulatorWeb/SimulatorWeb.tsx @@ -35,9 +35,9 @@ class SimulatorWeb extends Component { (window as any).setting = (this.setting as any); // TODO: 这里要读取存档 + const classicRender = new ClassicRenderer().onLoad(); this.status = new Status(); - this.status.renderer = new ClassicRenderer({ className: "canvas" }).onLoad(); - this.status.bindRenderer(this.status.renderer); + this.status.bindRenderer(classicRender); this.status.setting = this.setting; // 测试代码 diff --git a/source/Panel/GroupDetails/GroupDetails.tsx b/source/Panel/GroupDetails/GroupDetails.tsx index 51d94c2..299bc9e 100644 --- a/source/Panel/GroupDetails/GroupDetails.tsx +++ b/source/Panel/GroupDetails/GroupDetails.tsx @@ -4,7 +4,7 @@ import { useStatusWithEvent, IMixinStatusProps } from "@Context/Status"; import { useSetting, IMixinSettingProps } from "@Context/Setting"; import { ComboInput, IDisplayItem } from "@Input/ComboInput/ComboInput"; import { Message } from "@Input/Message/Message"; -import { ObjectID } from "@Model/Renderer"; +import { ObjectID } from "@Model/Model"; import { ColorInput } from "@Input/ColorInput/ColorInput"; import { TogglesInput } from "@Input/TogglesInput/TogglesInput"; import { LabelPicker } from "@Input/LabelPicker/LabelPicker"; @@ -13,6 +13,7 @@ import { AllI18nKeys } from "@Component/Localization/Localization"; import { ObjectPicker } from "@Input/ObjectPicker/ObjectPicker"; import { ConfirmPopup } from "@Component/ConfirmPopup/ConfirmPopup"; import { BehaviorPicker } from "@Input/BehaviorPicker/BehaviorPicker"; +import { Parameter } from "@Input/Parameter/Parameter"; import "./GroupDetails.scss"; interface IGroupDetailsProps {} @@ -54,14 +55,6 @@ class GroupDetails extends Component - { - this.props.status?.changeGroupAttrib(group.id, "size", (val as any) / 1); - }} - /> - + + key !== "color") + } + change={(key, value) => { + group.renderParameter[key as any] = value; + this.props.status?.changeGroupAttrib( + group.id, "renderParameter", group.renderParameter + ); + }} + /> diff --git a/source/Panel/ObjectList/ObjectCommand.tsx b/source/Panel/ObjectList/ObjectCommand.tsx index 97b856c..ff65e1d 100644 --- a/source/Panel/ObjectList/ObjectCommand.tsx +++ b/source/Panel/ObjectList/ObjectCommand.tsx @@ -2,7 +2,7 @@ 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/Model"; import { Icon } from "@fluentui/react"; import "./ObjectList.scss"; diff --git a/source/Panel/ObjectList/ObjectList.tsx b/source/Panel/ObjectList/ObjectList.tsx index 22a39aa..7961d26 100644 --- a/source/Panel/ObjectList/ObjectList.tsx +++ b/source/Panel/ObjectList/ObjectList.tsx @@ -3,7 +3,7 @@ import { useStatusWithEvent, IMixinStatusProps } from "@Context/Status"; import { useSetting, IMixinSettingProps } from "@Context/Setting"; import { Localization } from "@Component/Localization/Localization"; import { DetailsList } from "@Component/DetailsList/DetailsList"; -import { ObjectID } from "@Model/Renderer"; +import { ObjectID } from "@Model/Model"; import { Icon } from "@fluentui/react"; import "./ObjectList.scss"; diff --git a/source/Panel/RangeDetails/RangeDetails.tsx b/source/Panel/RangeDetails/RangeDetails.tsx index 81fe910..efe8eeb 100644 --- a/source/Panel/RangeDetails/RangeDetails.tsx +++ b/source/Panel/RangeDetails/RangeDetails.tsx @@ -3,11 +3,12 @@ import { useStatusWithEvent, IMixinStatusProps } from "@Context/Status"; import { AttrInput } from "@Input/AttrInput/AttrInput"; import { Message } from "@Input/Message/Message"; import { Range } from "@Model/Range"; -import { ObjectID } from "@Model/Renderer"; +import { ObjectID } from "@Model/Model"; import { ColorInput } from "@Input/ColorInput/ColorInput"; import { TogglesInput } from "@Input/TogglesInput/TogglesInput"; import { LabelPicker } from "@Input/LabelPicker/LabelPicker"; import { ConfirmPopup } from "@Component/ConfirmPopup/ConfirmPopup"; +import { Parameter } from "@Input/Parameter/Parameter"; import "./RangeDetails.scss"; @useStatusWithEvent("rangeAttrChange", "focusObjectChange", "rangeLabelChange") @@ -72,6 +73,23 @@ class RangeDetails extends Component { }} /> + key !== "color") + } + change={(key, value) => { + range.renderParameter[key as any] = value; + this.props.status?.changeRangeAttrib( + range.id, "renderParameter", range.renderParameter + ); + }} + /> +