(
new NumberInputDashboardExecutionState()
);
}
}
});
value: string;
min: string;
max: string;
step: string;
disableDefaultTabHandling: boolean;
override makeEditable() {
super.makeEditable();
makeObservable(this, {
value: observable,
min: observable,
max: observable,
step: observable,
disableDefaultTabHandling: observable
});
}
getOutputs(): ComponentOutput[] {
return [...super.getOutputs()];
}
getClassName(flowContext: IFlowContext) {
return classNames("eez-widget", this.type);
}
override render(flowContext: IFlowContext, width: number, height: number) {
const style: React.CSSProperties = {};
this.styleHook(style, flowContext);
const iterators =
flowContext.dataContext.get(FLOW_ITERATOR_INDEXES_VARIABLE) || [];
return (
<>
{super.render(flowContext, width, height)}
>
);
}
}
registerClass("NumberInputDashboardWidget", NumberInputDashboardWidget);
////////////////////////////////////////////////////////////////////////////////
export class CheckboxWidget extends Widget {
static classInfo = makeDerivedClassInfo(Widget.classInfo, {
enabledInComponentPalette: (projectType: ProjectType) =>
projectType === ProjectType.DASHBOARD,
componentPaletteGroupName: "!1Input",
properties: [
makeDataPropertyInfo("data", {
displayName: "Value"
}),
makeExpressionProperty(
{
name: "label",
type: PropertyType.MultilineText,
propertyGridGroup: specificGroup
},
"string"
),
makeDataPropertyInfo("enabled"),
makeStylePropertyInfo("style", "Default style")
],
defaultValue: {
left: 0,
top: 0,
width: 120,
height: 20
},
icon: (
),
widgetEvents: {
ON_CHANGE: {
code: 1,
paramExpressionType: `struct:${CHECKBOX_CHANGE_EVENT_STRUCT_NAME}`,
oldName: "action"
}
}
});
label: string;
enabled?: string;
override makeEditable() {
super.makeEditable();
makeObservable(this, {
label: observable,
enabled: observable
});
}
getOutputs(): ComponentOutput[] {
return [...super.getOutputs()];
}
getChecked(flowContext: IFlowContext) {
if (flowContext.projectStore.projectTypeTraits.hasFlowSupport) {
if (this.data) {
try {
return !!evalProperty(flowContext, this, "data");
} catch (err) {
//console.error(err);
}
}
return false;
}
if (this.data) {
return !!flowContext.dataContext.get(this.data);
}
return false;
}
getClassName(flowContext: IFlowContext) {
return classNames("eez-widget", this.type);
}
override render(
flowContext: IFlowContext,
width: number,
height: number
): React.ReactNode {
let checked = this.getChecked(flowContext);
const iterators =
flowContext.dataContext.get(FLOW_ITERATOR_INDEXES_VARIABLE) || [];
let index = iterators.length > 0 ? iterators[0] : 0;
let id = "c-" + guid();
if (index > 0) {
id = id + "-" + index;
}
const style: React.CSSProperties = {};
this.styleHook(style, flowContext);
const label = getTextValue(
flowContext,
this,
"label",
undefined,
this.label
);
let isEnabled = getBooleanValue(
flowContext,
this,
"enabled",
flowContext.flowState ? !this.enabled : true
);
return (
<>
{
const flowState =
flowContext.flowState as FlowState;
if (flowState) {
const value = event.target.checked;
if (this.data) {
assignProperty(
flowState,
this,
"data",
value,
iterators
);
}
if (flowState.runtime) {
flowState.runtime.executeWidgetAction(
flowContext,
this,
"ON_CHANGE",
makeCheckboxActionParamsValue(
flowContext,
value
),
`struct:${CHECKBOX_CHANGE_EVENT_STRUCT_NAME}`
);
}
}
}}
id={id}
disabled={!isEnabled}
>
{super.render(flowContext, width, height)}
>
);
}
}
registerClass("CheckboxWidget", CheckboxWidget);
////////////////////////////////////////////////////////////////////////////////
export class RadioWidget extends Widget {
static classInfo = makeDerivedClassInfo(Widget.classInfo, {
enabledInComponentPalette: (projectType: ProjectType) =>
projectType === ProjectType.DASHBOARD,
componentPaletteGroupName: "!1Input",
properties: [
makeDataPropertyInfo("data", {
hideInPropertyGrid: true
}),
makeExpressionProperty(
{
name: "label",
type: PropertyType.MultilineText,
propertyGridGroup: specificGroup
},
"string"
),
makeAssignableExpressionProperty(
{
name: "variable",
displayName: "Group variable",
type: PropertyType.MultilineText,
propertyGridGroup: specificGroup
},
"any"
),
makeExpressionProperty(
{
name: "value",
type: PropertyType.MultilineText,
propertyGridGroup: specificGroup
},
"any"
),
makeDataPropertyInfo("visible"),
makeDataPropertyInfo("enabled"),
makeStylePropertyInfo("style", "Default style")
],
defaultValue: {
left: 0,
top: 0,
width: 120,
height: 20
},
icon: (
),
widgetEvents: {
ON_CHANGE: {
code: 1,
paramExpressionType: `struct:${RADIO_CHANGE_EVENT_STRUCT_NAME}`,
oldName: "action"
}
}
});
label: string;
variable: string;
value: string;
enabled?: string;
override makeEditable() {
super.makeEditable();
makeObservable(this, {
label: observable,
variable: observable,
value: observable,
enabled: observable
});
}
getOutputs(): ComponentOutput[] {
return [...super.getOutputs()];
}
getClassName(flowContext: IFlowContext) {
return classNames("eez-widget", this.type);
}
override render(
flowContext: IFlowContext,
width: number,
height: number
): React.ReactNode {
const label = getTextValue(
flowContext,
this,
"label",
undefined,
this.label
);
let variable = getAnyValue(flowContext, this, "variable", true);
let value = getAnyValue(flowContext, this, "value", false);
let isEnabled = getBooleanValue(
flowContext,
this,
"enabled",
flowContext.flowState ? !this.enabled : true
);
const iterators =
flowContext.dataContext.get(FLOW_ITERATOR_INDEXES_VARIABLE) || [];
let index = iterators.length > 0 ? iterators[0] : 0;
let id = "CheckboxWidgetInput-" + getId(this);
if (index > 0) {
id = id + "-" + index;
}
const style: React.CSSProperties = {};
this.styleHook(style, flowContext);
return (
<>
{
const flowState =
flowContext.flowState as FlowState;
if (flowState) {
assignProperty(
flowState,
this,
"variable",
value,
iterators
);
if (flowState.runtime) {
flowState.runtime.executeWidgetAction(
flowContext,
this,
"ON_CHANGE",
makeRadioActionParamsValue(
flowContext,
event.target.checked
),
`struct:${RADIO_CHANGE_EVENT_STRUCT_NAME}`
);
}
}
}}
id={id}
disabled={!isEnabled}
>
{super.render(flowContext, width, height)}
>
);
}
}
registerClass("RadioWidget", RadioWidget);
////////////////////////////////////////////////////////////////////////////////
export class SwitchDashboardWidget extends Widget {
static classInfo = makeDerivedClassInfo(Widget.classInfo, {
enabledInComponentPalette: (projectType: ProjectType) =>
projectType === ProjectType.DASHBOARD,
componentPaletteGroupName: "!1Input",
properties: [
makeDataPropertyInfo("data", {
displayName: "Value"
}),
makeDataPropertyInfo("enabled"),
makeStylePropertyInfo("style", "Default style")
],
defaultValue: {
left: 0,
top: 0,
width: 64,
height: 32
},
icon: SWITCH_WIDGET_ICON,
widgetEvents: {
ON_CHANGE: {
code: 1,
paramExpressionType: `struct:${SWITCH_CHANGE_EVENT_STRUCT_NAME}`,
oldName: "action"
}
}
});
enabled?: string;
override makeEditable() {
super.makeEditable();
makeObservable(this, {
enabled: observable
});
}
getOutputs(): ComponentOutput[] {
return [...super.getOutputs()];
}
getChecked(flowContext: IFlowContext) {
if (flowContext.projectStore.projectTypeTraits.hasFlowSupport) {
if (this.data) {
try {
return !!evalProperty(flowContext, this, "data");
} catch (err) {
//console.error(err);
}
}
return false;
}
if (this.data) {
return !!flowContext.dataContext.get(this.data);
}
return false;
}
getClassName(flowContext: IFlowContext) {
return classNames("eez-widget", this.type);
}
override render(
flowContext: IFlowContext,
width: number,
height: number
): React.ReactNode {
let checked = this.getChecked(flowContext);
const style: React.CSSProperties = {};
this.styleHook(style, flowContext);
let isEnabled = getBooleanValue(
flowContext,
this,
"enabled",
flowContext.flowState ? !this.enabled : true
);
const iterators =
flowContext.dataContext.get(FLOW_ITERATOR_INDEXES_VARIABLE) || [];
return (
<>
{
const flowState =
flowContext.flowState as FlowState;
if (flowState) {
const value = event.target.checked;
if (this.data) {
assignProperty(
flowState,
this,
"data",
value,
iterators
);
}
if (flowState.runtime) {
flowState.runtime.executeWidgetAction(
flowContext,
this,
"ON_CHANGE",
makeCheckboxActionParamsValue(
flowContext,
value
),
`struct:${CHECKBOX_CHANGE_EVENT_STRUCT_NAME}`
);
}
}
}}
disabled={!isEnabled}
>
{super.render(flowContext, width, height)}
>
);
}
}
registerClass("SwitchDashboardWidget", SwitchDashboardWidget);
////////////////////////////////////////////////////////////////////////////////
export class DropDownListDashboardWidget extends Widget {
options: string;
enabled?: string;
static classInfo = makeDerivedClassInfo(Widget.classInfo, {
enabledInComponentPalette: (projectType: ProjectType) =>
projectType === ProjectType.DASHBOARD,
componentPaletteGroupName: "!1Input",
componentPaletteLabel: "Dropdown",
properties: [
makeDataPropertyInfo("data", {}, "integer"),
makeDataPropertyInfo("options"),
makeDataPropertyInfo("enabled"),
makeStylePropertyInfo("style", "Default style")
],
beforeLoadHook: (
widget: DropDownListDashboardWidget,
jsWidget: Partial
) => {
jsWidget.type = "DropDownListDashboardWidget";
},
defaultValue: {
left: 0,
top: 0,
width: 120,
height: 32
},
icon: (
),
widgetEvents: {
ON_CHANGE: {
code: 1,
paramExpressionType: `struct:${DROP_DOWN_LIST_CHANGE_EVENT_STRUCT_NAME}`,
oldName: "action"
}
}
});
override makeEditable() {
super.makeEditable();
makeObservable(this, {
options: observable,
enabled: observable
});
}
override render(flowContext: IFlowContext, width: number, height: number) {
let options: string[] = evalProperty(flowContext, this, "options");
if (options == undefined || !isArray(options)) {
options = [];
}
let selectedIndex: number = evalProperty(flowContext, this, "data");
let isEnabled = getBooleanValue(
flowContext,
this,
"enabled",
flowContext.flowState ? !this.enabled : true
);
const iterators =
flowContext.dataContext.get(FLOW_ITERATOR_INDEXES_VARIABLE) || [];
return (
<>
{super.render(flowContext, width, height)}
>
);
}
}
registerClass("DropDownListDashboardWidget", DropDownListDashboardWidget);
////////////////////////////////////////////////////////////////////////////////
export class ProgressDashboardWidget extends Widget {
static classInfo = makeDerivedClassInfo(Widget.classInfo, {
enabledInComponentPalette: (projectType: ProjectType) =>
projectType === ProjectType.DASHBOARD,
componentPaletteGroupName: "!1Visualiser",
properties: [
makeDataPropertyInfo("data", {}, "integer"),
makeDataPropertyInfo("min"),
makeDataPropertyInfo("max"),
{
name: "orientation",
type: PropertyType.Enum,
propertyGridGroup: specificGroup,
enumItems: [
{
id: "horizontal"
},
{
id: "vertical"
}
]
},
makeStylePropertyInfo("style", "Default style")
],
beforeLoadHook: (
progressWidget: ProgressDashboardWidget,
jsProgressWidget: Partial,
project: Project
) => {
jsProgressWidget.type = "ProgressDashboardWidget";
if (project.projectTypeTraits.hasFlowSupport) {
if (jsProgressWidget.min == undefined) {
jsProgressWidget.min = "0";
}
if (jsProgressWidget.max == undefined) {
jsProgressWidget.max = "100";
}
}
if (jsProgressWidget.orientation == undefined) {
jsProgressWidget.orientation =
jsProgressWidget.width! > jsProgressWidget.height!
? "horizontal"
: "vertical";
}
},
defaultValue: {
left: 0,
top: 0,
width: 128,
height: 20
},
icon: (
)
});
min: string;
max: string;
orientation: string;
override makeEditable() {
super.makeEditable();
makeObservable(this, {
min: observable,
max: observable,
orientation: observable
});
}
getPercent(flowContext: IFlowContext) {
if (flowContext.projectStore.projectTypeTraits.hasFlowSupport) {
if (flowContext.flowState) {
try {
const min = evalProperty(flowContext, this, "min");
const max = evalProperty(flowContext, this, "max");
let value = evalProperty(flowContext, this, "data");
value = ((value - min) * 100) / (max - min);
if (value != null && value != undefined) {
return value;
}
} catch (err) {
//console.error(err);
}
return 0;
}
return 25;
}
if (this.data) {
const result = flowContext.dataContext.get(this.data);
if (result != undefined) {
return result;
}
}
return 25;
}
override render(flowContext: IFlowContext, width: number, height: number) {
const percent = this.getPercent(flowContext);
let isHorizontal = this.orientation == "horizontal";
return (
<>
{super.render(flowContext, width, height)}
>
);
}
}
registerClass("ProgressDashboardWidget", ProgressDashboardWidget);
////////////////////////////////////////////////////////////////////////////////
export class SpinnerWidget extends Widget {
static classInfo = makeDerivedClassInfo(Widget.classInfo, {
enabledInComponentPalette: (projectType: ProjectType) =>
projectType === ProjectType.DASHBOARD,
componentPaletteGroupName: "!1Visualiser",
properties: [makeStylePropertyInfo("style", "Default style")],
defaultValue: {
left: 0,
top: 0,
width: 40,
height: 40
},
icon: (
)
});
override makeEditable() {
super.makeEditable();
makeObservable(this, {});
}
override render(
flowContext: IFlowContext,
width: number,
height: number
): React.ReactNode {
return ;
}
}
registerClass("SpinnerWidget", SpinnerWidget);
////////////////////////////////////////////////////////////////////////////////
export class QRCodeDashboardWidget extends Widget {
errorCorrection: any;
constructor() {
super();
makeObservable(this, {
errorCorrectionValue: computed
});
}
override makeEditable() {
super.makeEditable();
makeObservable(this, {
errorCorrection: observable
});
}
static classInfo = makeDerivedClassInfo(Widget.classInfo, {
enabledInComponentPalette: (projectType: ProjectType) =>
projectType === ProjectType.DASHBOARD,
componentPaletteGroupName: "!1Visualiser",
properties: [
makeDataPropertyInfo("data", {
displayName: "Text"
}),
{
name: "errorCorrection",
type: PropertyType.Enum,
enumItems: [
{
id: "low"
},
{
id: "medium"
},
{
id: "quartile"
},
{
id: "high"
}
],
propertyGridGroup: specificGroup
},
makeStylePropertyInfo("style", "Default style")
],
beforeLoadHook: (
widget: QRCodeDashboardWidget,
jsWidget: Partial
) => {
jsWidget.type = "QRCodeDashboardWidget";
},
defaultValue: {
left: 0,
top: 0,
width: 128,
height: 128,
errorCorrection: "medium",
style: {
useStyle: "default",
color: "white",
backgroundColor: "black"
}
},
icon: (
)
});
getText(flowContext: IFlowContext) {
if (!this.data) {
return undefined;
}
if (flowContext.projectStore.projectTypeTraits.hasFlowSupport) {
return evalProperty(flowContext, this, "data");
}
return this.data;
}
get errorCorrectionValue() {
if (this.errorCorrection == "low") return QRC.Ecc.LOW;
if (this.errorCorrection == "medium") return QRC.Ecc.MEDIUM;
if (this.errorCorrection == "quartile") return QRC.Ecc.QUARTILE;
return QRC.Ecc.HIGH;
}
styleHook(style: React.CSSProperties, flowContext: IFlowContext) {
super.styleHook(style, flowContext);
style.backgroundColor = to16bitsColor(
this.style.backgroundColorProperty
);
}
static toSvgString(
qr: any,
border: number,
lightColor: string,
darkColor: string
) {
let parts: Array = [];
for (let y = 0; y < qr.size; y++) {
for (let x = 0; x < qr.size; x++) {
if (qr.getModule(x, y))
parts.push(`M${x + border},${y + border}h1v1h-1z`);
}
}
return (
);
}
override render(flowContext: IFlowContext, width: number, height: number) {
const text = this.getText(flowContext) || "";
const qr0 = QRC.encodeText(text, this.errorCorrectionValue);
const svg = QRCodeDashboardWidget.toSvgString(
qr0,
1,
to16bitsColor(this.style.backgroundColorProperty),
to16bitsColor(this.style.colorProperty)
);
return (
<>
{svg}
{super.render(flowContext, width, height)}
>
);
}
}
registerClass("QRCodeDashboardWidget", QRCodeDashboardWidget);
////////////////////////////////////////////////////////////////////////////////
export class ButtonDashboardWidget extends Widget {
enabled?: string;
disabledStyle: Style;
static classInfo = makeDerivedClassInfo(Widget.classInfo, {
enabledInComponentPalette: (projectType: ProjectType) =>
projectType === ProjectType.DASHBOARD,
properties: [
makeDataPropertyInfo("data", {
displayName: "Label"
}),
makeDataPropertyInfo("enabled"),
makeStylePropertyInfo("style", "Default style"),
makeStylePropertyInfo("disabledStyle")
],
beforeLoadHook: (
widget: IEezObject,
jsObject: any,
project: Project
) => {
jsObject.type = "ButtonDashboardWidget";
if (jsObject.text) {
if (!jsObject.data) {
jsObject.data = `"${jsObject.text}"`;
}
delete jsObject.text;
}
migrateStyleProperty(jsObject, "disabledStyle");
},
defaultValue: {
left: 0,
top: 0,
width: 80,
height: 40,
data: `"Button"`,
eventHandlers: [
{
eventName: "CLICKED",
handlerType: "flow"
}
]
},
icon: (
),
check: (widget: ButtonDashboardWidget, messages: IMessage[]) => {
const project = ProjectEditor.getProject(widget);
if (!project.projectTypeTraits.hasFlowSupport) {
if (!widget.data && !widget.isInputProperty("data")) {
messages.push(propertyNotSetMessage(widget, "text"));
}
checkObjectReference(widget, "enabled", messages, true);
} else {
if (!widget.data) {
messages.push(propertyNotSetMessage(widget, "text"));
}
}
}
});
override makeEditable() {
super.makeEditable();
makeObservable(this, {
enabled: observable,
disabledStyle: observable
});
}
get styles() {
return [this.style, this.disabledStyle];
}
getClassName(flowContext: IFlowContext) {
return classNames("eez-widget", this.type);
}
override render(flowContext: IFlowContext, width: number, height: number) {
const result = getTextValue(flowContext, this, "data", undefined, "");
let text: string;
let node: React.ReactNode | null;
if (typeof result == "object") {
text = result.text;
node = result.node;
} else {
text = result;
node = null;
}
let buttonEnabled = getBooleanValue(
flowContext,
this,
"enabled",
flowContext.flowState ? !this.enabled : true
);
let buttonStyle = buttonEnabled ? this.style : this.disabledStyle;
const style: React.CSSProperties = {};
this.styleHook(style, flowContext);
return (
<>
{super.render(flowContext, width, height)}
>
);
}
}
registerClass("ButtonDashboardWidget", ButtonDashboardWidget);
////////////////////////////////////////////////////////////////////////////////
const BitmapWidgetPropertyGridUI = observer(
class BitmapWidgetPropertyGridUI extends React.Component {
get bitmapWidget() {
return this.props.objects[0] as BitmapDashboardWidget;
}
resizeToFitBitmap = () => {
getProjectStore(this.props.objects[0]).updateObject(
this.props.objects[0],
{
width: this.bitmapWidget.bitmapObject!.imageElement!.width,
height: this.bitmapWidget.bitmapObject!.imageElement!.height
}
);
};
render() {
if (this.props.readOnly) {
return null;
}
if (this.props.objects.length > 1) {
return null;
}
const bitmapObject = this.bitmapWidget.bitmapObject;
if (!bitmapObject) {
return null;
}
const imageElement = bitmapObject.imageElement;
if (!imageElement) {
return null;
}
const widget = this.props.objects[0] as Widget;
if (
widget.width == imageElement.width &&
widget.height == imageElement.height
) {
return null;
}
return (
);
}
}
);
////////////////////////////////////////////////////////////////////////////////
export class BitmapDashboardWidget extends Widget {
bitmap?: string;
constructor() {
super();
makeObservable(this, {
bitmapObject: computed
});
}
override makeEditable() {
super.makeEditable();
makeObservable(this, {
bitmap: observable
});
}
get label() {
return this.bitmap ? `${this.type}: ${this.bitmap}` : this.type;
}
static classInfo = makeDerivedClassInfo(Widget.classInfo, {
enabledInComponentPalette: (projectType: ProjectType) =>
projectType === ProjectType.DASHBOARD,
properties: [
makeDataPropertyInfo("data", {}, "any"),
{
name: "bitmap",
type: PropertyType.ObjectReference,
referencedObjectCollectionPath: "bitmaps",
propertyGridGroup: specificGroup
},
{
name: "customUI",
type: PropertyType.Any,
propertyGridGroup: specificGroup,
computed: true,
propertyGridRowComponent: BitmapWidgetPropertyGridUI
},
makeStylePropertyInfo("style", "Default style")
],
beforeLoadHook: (widget: Widget, jsObject: any, project: Project) => {
jsObject.type = "BitmapDashboardWidget";
},
defaultValue: {
left: 0,
top: 0,
width: 64,
height: 32
},
icon: (
),
check: (object: BitmapDashboardWidget, messages: IMessage[]) => {
if (!object.data && !object.bitmap) {
messages.push(
new Message(
MessageType.ERROR,
"Either bitmap or data must be set",
object
)
);
} else {
if (object.data && object.bitmap) {
messages.push(
new Message(
MessageType.ERROR,
"Both bitmap and data set, only bitmap is used",
object
)
);
}
if (object.bitmap) {
let bitmap = findBitmap(getProject(object), object.bitmap);
if (!bitmap) {
messages.push(
propertyNotFoundMessage(object, "bitmap")
);
}
}
}
}
});
get bitmapObject() {
return this.getBitmapObject(getProjectStore(this).dataContext);
}
getBitmapObject(dataContext: IDataContext) {
return this.bitmap
? findBitmap(getProject(this), this.bitmap)
: this.data
? findBitmap(getProject(this), dataContext.get(this.data) as string)
: undefined;
}
getBitmap(flowContext: IFlowContext) {
if (this.bitmap) {
return findBitmap(getProject(this), this.bitmap);
}
if (this.data) {
let data;
if (flowContext.flowState) {
data = evalProperty(flowContext, this, "data");
} else {
data = flowContext.dataContext.get(this.data);
}
if (typeof data === "string") {
if (data.startsWith("data:image/png;base64,")) {
return data;
}
const bitmap = findBitmap(getProject(this), data as string);
if (bitmap) {
return bitmap;
}
return undefined;
}
if (data instanceof Uint8Array) {
const { detectFileType } =
require("instrument/connection/file-type") as typeof FileTypeModule;
const fileType = detectFileType(data);
return URL.createObjectURL(
new Blob([data], { type: fileType.mime } /* (1) */)
);
}
if (typeof data == "number") {
const runtime = flowContext.flowState?.runtime;
if (runtime instanceof WasmRuntime) {
const bitmap = findBitmap(
getProject(this),
runtime.assetsMap.bitmaps[data - 1]
);
if (bitmap) {
return bitmap;
}
return undefined;
}
}
return data;
}
return undefined;
}
override render(flowContext: IFlowContext, width: number, height: number) {
const bitmap = this.getBitmap(flowContext);
return (
<>
{bitmap ? (
bitmap instanceof Bitmap ? (
) : (
)
) : null}
{super.render(flowContext, width, height)}
>
);
}
}
registerClass("BitmapDashboardWidget", BitmapDashboardWidget);
////////////////////////////////////////////////////////////////////////////////
const SliderDashboardWidgetElement = observer(
class SliderDashboardWidgetElement extends React.Component<{
component: SliderDashboardWidget;
flowContext: IFlowContext;
width: number;
height: number;
}> {
constructor(props: any) {
super(props);
makeObservable(this, {
currentValue: observable
});
}
onChangeTimer: any;
currentValue: any;
render() {
const { flowContext, component } = this.props;
let value =
this.currentValue != undefined
? this.currentValue
: evalProperty(flowContext, component, "value") ?? 25;
let min = evalProperty(flowContext, component, "min") ?? 0;
let max = evalProperty(flowContext, component, "max") ?? 100;
let viewMin =
evalProperty(flowContext, component, "viewMin") ?? min;
let viewMax =
evalProperty(flowContext, component, "viewMax") ?? max;
let step = evalProperty(flowContext, component, "step") ?? 1;
if (min < viewMin) {
viewMin = min;
}
if (max > viewMax) {
viewMax = max;
}
let isEnabled = getBooleanValue(
flowContext,
component,
"enabled",
flowContext.flowState ? !component.enabled : true
);
const iterators =
flowContext.dataContext.get(FLOW_ITERATOR_INDEXES_VARIABLE) ||
[];
return (
{
let value = parseFloat(event.target.value);
if (value < min) {
value = min;
}
if (value > max) {
value = max;
}
runInAction(() => {
this.currentValue = value;
});
if (this.onChangeTimer) {
return;
}
this.onChangeTimer = setTimeout(() => {
const flowState =
flowContext.flowState as FlowState;
if (flowState) {
if (component.value) {
assignProperty(
flowState,
component,
"value",
this.currentValue,
iterators
);
runInAction(() => {
this.currentValue = undefined;
});
}
if (flowState.runtime) {
flowState.runtime.executeWidgetAction(
flowContext,
component,
"ON_CHANGE",
makeSliderActionParamsValue(
flowContext,
value
),
`struct:${SLIDER_CHANGE_EVENT_STRUCT_NAME}`
);
}
}
this.onChangeTimer = undefined;
}, 20);
}}
disabled={!isEnabled}
>
);
}
}
);
export class SliderDashboardWidget extends Widget {
static classInfo = makeDerivedClassInfo(Widget.classInfo, {
enabledInComponentPalette: (projectType: ProjectType) =>
projectType === ProjectType.DASHBOARD,
componentPaletteGroupName: "!1Input",
properties: [
makeDataPropertyInfo("data", {
hideInPropertyGrid: true
}),
makeExpressionProperty(
{
name: "value",
type: PropertyType.MultilineText,
propertyGridGroup: specificGroup
},
"double"
),
makeExpressionProperty(
{
name: "min",
type: PropertyType.MultilineText,
propertyGridGroup: specificGroup
},
"double"
),
makeExpressionProperty(
{
name: "max",
type: PropertyType.MultilineText,
propertyGridGroup: specificGroup
},
"double"
),
makeExpressionProperty(
{
name: "step",
type: PropertyType.MultilineText,
propertyGridGroup: specificGroup
},
"double"
),
makeExpressionProperty(
{
name: "viewMin",
type: PropertyType.MultilineText,
propertyGridGroup: specificGroup
},
"double"
),
makeExpressionProperty(
{
name: "viewMax",
type: PropertyType.MultilineText,
propertyGridGroup: specificGroup
},
"double"
),
makeDataPropertyInfo("enabled"),
makeStylePropertyInfo("style", "Default style")
],
beforeLoadHook: (widget: Widget, jsObject: any, project: Project) => {
if (jsObject.step == undefined) {
jsObject.step = "1";
}
if (jsObject.viewMin == undefined) {
jsObject.viewMin = jsObject.min;
}
if (jsObject.viewMax == undefined) {
jsObject.viewMax = jsObject.max;
}
},
defaultValue: {
left: 0,
top: 0,
width: 180,
height: 20,
min: "0",
max: "100",
step: "1",
viewMin: "0",
viewMax: "100"
},
icon: (
),
widgetEvents: {
ON_CHANGE: {
code: 1,
paramExpressionType: `struct:${SLIDER_CHANGE_EVENT_STRUCT_NAME}`,
oldName: "action"
}
}
});
value: string;
min: string;
max: string;
viewMin: string;
viewMax: string;
enabled?: string;
override makeEditable() {
super.makeEditable();
makeObservable(this, {
value: observable,
min: observable,
max: observable,
viewMin: observable,
viewMax: observable,
enabled: observable
});
}
getOutputs(): ComponentOutput[] {
return [...super.getOutputs()];
}
getClassName(flowContext: IFlowContext) {
return classNames("eez-widget", this.type);
}
override render(flowContext: IFlowContext, width: number, height: number) {
return (
<>
{super.render(flowContext, width, height)}
>
);
}
}
registerClass("SliderDashboardWidget", SliderDashboardWidget);
////////////////////////////////////////////////////////////////////////////////
import "project-editor/flow/components/widgets/dashboard/eez-chart";
import "project-editor/flow/components/widgets/dashboard/markdown";
import "project-editor/flow/components/widgets/dashboard/plotly";
import "project-editor/flow/components/widgets/dashboard/tabulator";
import "project-editor/flow/components/widgets/dashboard/terminal";
import "project-editor/flow/components/widgets/dashboard/instrument-terminal";
import "project-editor/flow/components/widgets/dashboard/embedded-dashboard";
import { assignProperty } from "project-editor/flow/runtime/worker-dashboard-component-context";
import { guid } from "eez-studio-shared/guid";
import { IDashboardComponentContext } from "eez-studio-types";