From 38479ea5735bb2ff57439910f2c16d4e3b0ae2a6 Mon Sep 17 00:00:00 2001 From: NatLeung96 Date: Wed, 9 Apr 2025 10:29:29 +0100 Subject: [PATCH 01/18] Added styling --- src/ui/widgets/MenuButton/menuButton.tsx | 71 +++++++++++++++++++----- 1 file changed, 57 insertions(+), 14 deletions(-) diff --git a/src/ui/widgets/MenuButton/menuButton.tsx b/src/ui/widgets/MenuButton/menuButton.tsx index bd2fd48a..3abbd09d 100644 --- a/src/ui/widgets/MenuButton/menuButton.tsx +++ b/src/ui/widgets/MenuButton/menuButton.tsx @@ -7,7 +7,9 @@ import { BoolPropOpt, ColorPropOpt, InferWidgetProps, - StringPropOpt + StringArrayPropOpt, + StringPropOpt, + FontPropOpt } from "../propTypes"; import { DType } from "../../../types/dtypes"; import { @@ -21,6 +23,9 @@ import { import { FileContext } from "../../../misc/fileContext"; import { Border } from "../../../types/border"; import { Color } from "../../../types/color"; +import { MenuItem, Select } from "@mui/material"; +import { diamondTheme } from "../../../diamondTheme"; +import { Font } from "../../../types"; export interface MenuButtonProps { connected: boolean; @@ -35,6 +40,8 @@ export interface MenuButtonProps { foregroundColor?: Color; backgroundColor?: Color; border?: Border; + font?: Font; + items?: string[]; } export const MenuButtonComponent = (props: MenuButtonProps): JSX.Element => { @@ -45,7 +52,8 @@ export const MenuButtonComponent = (props: MenuButtonProps): JSX.Element => { actionsFromPv = true, itemsFromPv = false, pvName, - label + label, + items = ["Item 1", "Item 2"] } = props; const fromPv = actionsFromPv || itemsFromPv; let actions: WidgetAction[] = props.actions?.actions || []; @@ -95,15 +103,19 @@ export const MenuButtonComponent = (props: MenuButtonProps): JSX.Element => { cursor: disabled ? "not-allowed" : "default" }; - const mappedOptions = options.map((text, index): JSX.Element => { + const mappedOptions = items.map((text, index): JSX.Element => { return ( - + ); }); @@ -116,18 +128,43 @@ export const MenuButtonComponent = (props: MenuButtonProps): JSX.Element => { } return ( - + ); }; @@ -143,6 +180,8 @@ export const SmartMenuButton = (props: { foregroundColor?: Color; backgroundColor?: Color; border?: Border; + items?: string[]; + font?: Font; }): JSX.Element => { const files = useContext(FileContext); // Function to send the value on to the PV @@ -164,6 +203,8 @@ export const SmartMenuButton = (props: { label={props.label} foregroundColor={props.foregroundColor} backgroundColor={props.backgroundColor} + items={props.items} + font={props.font} /> ); }; @@ -174,7 +215,9 @@ const MenuButtonWidgetProps = { itemsFromPv: BoolPropOpt, label: StringPropOpt, foregroundColor: ColorPropOpt, - backgroundColor: ColorPropOpt + backgroundColor: ColorPropOpt, + items: StringArrayPropOpt, + font: FontPropOpt }; export const MenuButton = ( From 0a5e18e20d8191a3bde1977c1127425b8e107a78 Mon Sep 17 00:00:00 2001 From: NatLeung96 Date: Wed, 9 Apr 2025 16:52:49 +0100 Subject: [PATCH 02/18] Setup placeholder until option is clicked --- src/ui/widgets/MenuButton/menuButton.tsx | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/ui/widgets/MenuButton/menuButton.tsx b/src/ui/widgets/MenuButton/menuButton.tsx index 3abbd09d..a7b1e706 100644 --- a/src/ui/widgets/MenuButton/menuButton.tsx +++ b/src/ui/widgets/MenuButton/menuButton.tsx @@ -1,4 +1,4 @@ -import React, { CSSProperties, useContext } from "react"; +import React, { CSSProperties, useContext, useState } from "react"; import { commonCss, Widget } from "../widget"; import { PVWidgetPropType } from "../widgetProps"; @@ -106,9 +106,9 @@ export const MenuButtonComponent = (props: MenuButtonProps): JSX.Element => { const mappedOptions = items.map((text, index): JSX.Element => { return ( { } } + const [selected, setSelected] = useState(""); + return ( - ); return ( -
- {inp} - -
+ + } + label={props.label} + /> ); }; From 66eb3159b4153b63110669931c185fa30820acdb Mon Sep 17 00:00:00 2001 From: NatLeung96 Date: Thu, 10 Apr 2025 13:02:05 +0100 Subject: [PATCH 06/18] Tidied nested for-loop --- src/ui/widgets/MenuButton/menuButton.tsx | 45 ++++++++++++------------ 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/src/ui/widgets/MenuButton/menuButton.tsx b/src/ui/widgets/MenuButton/menuButton.tsx index a7b1e706..e3e6e742 100644 --- a/src/ui/widgets/MenuButton/menuButton.tsx +++ b/src/ui/widgets/MenuButton/menuButton.tsx @@ -68,31 +68,29 @@ export const MenuButtonComponent = (props: MenuButtonProps): JSX.Element => { // Show 0 by default where there is only one option let displayIndex = 0; - if (fromPv && pvName) { - if (!connected || value === null) { - disabled = true; - } else if (value?.display?.choices) { - options = options.concat(value?.display?.choices); - actions = options.map((option, i) => { - const writePv: WritePv = { - type: WRITE_PV, - writePvInfo: { - pvName: pvName, - value: i - } - }; - return writePv; - }); - displayIndex = (value.getDoubleValue() ?? 0) + displayOffset; - } else { - disabled = true; - } - } else { + if (!(fromPv && pvName)) { options = options.concat( actions.map(action => { return getActionDescription(action); }) ); + } else if (!connected || value === null) { + disabled = true; + } else if (value?.display?.choices) { + options = options.concat(value?.display?.choices); + actions = options.map((option, i) => { + const writePv: WritePv = { + type: WRITE_PV, + writePvInfo: { + pvName: pvName, + value: i + } + }; + return writePv; + }); + displayIndex = (value.getDoubleValue() ?? 0) + displayOffset; + } else { + disabled = true; } const style: CSSProperties = { @@ -107,8 +105,8 @@ export const MenuButtonComponent = (props: MenuButtonProps): JSX.Element => { return ( { } }} renderValue={value => { - if (!value) { + if (value === "") { return "Name"; } return selected; @@ -162,6 +160,7 @@ export const MenuButtonComponent = (props: MenuButtonProps): JSX.Element => { }, "& .MuiSelect-outlined": { fontFamily: props.font?.css() ?? "", + color: props.foregroundColor?.toString() ?? "" } }} From 8e2ec5b6075b166e278727f463214752dd8b998f Mon Sep 17 00:00:00 2001 From: NatLeung96 Date: Mon, 14 Apr 2025 15:47:54 +0100 Subject: [PATCH 07/18] Tidied up styling and prop definitions --- src/ui/widgets/MenuButton/menuButton.tsx | 131 ++++++++++++----------- 1 file changed, 67 insertions(+), 64 deletions(-) diff --git a/src/ui/widgets/MenuButton/menuButton.tsx b/src/ui/widgets/MenuButton/menuButton.tsx index e3e6e742..175e50c4 100644 --- a/src/ui/widgets/MenuButton/menuButton.tsx +++ b/src/ui/widgets/MenuButton/menuButton.tsx @@ -1,6 +1,6 @@ -import React, { CSSProperties, useContext, useState } from "react"; +import React, { useContext } from "react"; -import { commonCss, Widget } from "../widget"; +import { Widget } from "../widget"; import { PVWidgetPropType } from "../widgetProps"; import { registerWidget } from "../register"; import { @@ -9,7 +9,13 @@ import { InferWidgetProps, StringArrayPropOpt, StringPropOpt, - FontPropOpt + FontPropOpt, + ActionsPropType, + // BoolProp, + // DTypeProp, + // FuncProp, + // DTypePropOpt, + FuncPropOpt } from "../propTypes"; import { DType } from "../../../types/dtypes"; import { @@ -42,24 +48,49 @@ export interface MenuButtonProps { border?: Border; font?: Font; items?: string[]; + enabled?: boolean; } -export const MenuButtonComponent = (props: MenuButtonProps): JSX.Element => { +const MenuButtonComponentProps = { + pvName: StringPropOpt, + foregroundColor: ColorPropOpt, + backgroundColor: ColorPropOpt, + font: FontPropOpt, + enabled: BoolPropOpt, + // value: DTypePropOpt, + actions: ActionsPropType, + connected: BoolPropOpt, + onChange: FuncPropOpt, + // opi specific prop + readonly: BoolPropOpt, + actionsFromPv: BoolPropOpt, + label: StringPropOpt, + // bob specific prop + items: StringArrayPropOpt, + itemsFromPv: BoolPropOpt +}; + +export const MenuButtonComponent = ( + props: MenuButtonProps + // props: InferWidgetProps +): JSX.Element => { const { connected, value = null, - readonly, + enabled = true, actionsFromPv = true, - itemsFromPv = false, + itemsFromPv = true, pvName, label, - items = ["Item 1", "Item 2"] + items = ["Item 1", "Item 2"], + foregroundColor = diamondTheme.palette.primary.contrastText, + backgroundColor = diamondTheme.palette.primary.main } = props; - const fromPv = actionsFromPv || itemsFromPv; - let actions: WidgetAction[] = props.actions?.actions || []; + const fromPv = actionsFromPv && itemsFromPv; + let actions: WidgetAction[] = props.actions?.actions ?? []; // Store whether component is disabled or not - let disabled = readonly; + let disabled = !enabled; let options: string[] = label ? [label] : []; const displayOffset = label ? 1 : 0; @@ -93,23 +124,14 @@ export const MenuButtonComponent = (props: MenuButtonProps): JSX.Element => { disabled = true; } - const style: CSSProperties = { - ...commonCss(props), - width: "100%", - height: "100%", - textAlignLast: "center", - cursor: disabled ? "not-allowed" : "default" - }; - const mappedOptions = items.map((text, index): JSX.Element => { return ( {text} @@ -119,58 +141,54 @@ export const MenuButtonComponent = (props: MenuButtonProps): JSX.Element => { /* Don't disable the element itself because that prevents any interaction even for ancestor elements, including middle-click copy. */ - function onMouseDown(event: React.MouseEvent): void { + function onMouseDown(event: React.MouseEvent): void { if (disabled) { event.preventDefault(); } } - const [selected, setSelected] = useState(""); - return ( @@ -178,20 +196,10 @@ export const MenuButtonComponent = (props: MenuButtonProps): JSX.Element => { }; // Menu button which also knows how to write to a PV -export const SmartMenuButton = (props: { - connected: boolean; - pvName: string; - value?: DType; - readonly: boolean; - actionsFromPv?: boolean; - actions?: WidgetActions; - label?: string; - foregroundColor?: Color; - backgroundColor?: Color; - border?: Border; - items?: string[]; - font?: Font; -}): JSX.Element => { +export const SmartMenuButton = ( + props: MenuButtonProps + // props: InferWidgetProps +): JSX.Element => { const files = useContext(FileContext); // Function to send the value on to the PV function onChange(action: WidgetAction): void { @@ -207,6 +215,7 @@ export const SmartMenuButton = (props: { value={props.value} readonly={props.readonly} actionsFromPv={props.actionsFromPv} + itemsFromPv={props.itemsFromPv} actions={props.actions} onChange={onChange} label={props.label} @@ -219,18 +228,12 @@ export const SmartMenuButton = (props: { }; const MenuButtonWidgetProps = { - ...PVWidgetPropType, - actionsFromPv: BoolPropOpt, - itemsFromPv: BoolPropOpt, - label: StringPropOpt, - foregroundColor: ColorPropOpt, - backgroundColor: ColorPropOpt, - items: StringArrayPropOpt, - font: FontPropOpt + ...MenuButtonComponentProps, + ...PVWidgetPropType }; export const MenuButton = ( props: InferWidgetProps ): JSX.Element => ; -registerWidget(MenuButton, MenuButtonWidgetProps, "menubutton"); +registerWidget(MenuButton, MenuButtonComponentProps, "menubutton"); From 436fe922e2e36f2945f84e246d503cbe7500a912 Mon Sep 17 00:00:00 2001 From: NatLeung96 Date: Tue, 15 Apr 2025 09:03:27 +0100 Subject: [PATCH 08/18] Added DType proptypes --- src/ui/widgets/MenuButton/menuButton.tsx | 13 +++---------- src/ui/widgets/propTypes.ts | 4 ++++ 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/ui/widgets/MenuButton/menuButton.tsx b/src/ui/widgets/MenuButton/menuButton.tsx index 175e50c4..245d1005 100644 --- a/src/ui/widgets/MenuButton/menuButton.tsx +++ b/src/ui/widgets/MenuButton/menuButton.tsx @@ -11,11 +11,8 @@ import { StringPropOpt, FontPropOpt, ActionsPropType, - // BoolProp, - // DTypeProp, - // FuncProp, - // DTypePropOpt, - FuncPropOpt + FuncPropOpt, + DTypePropOpt } from "../propTypes"; import { DType } from "../../../types/dtypes"; import { @@ -57,7 +54,7 @@ const MenuButtonComponentProps = { backgroundColor: ColorPropOpt, font: FontPropOpt, enabled: BoolPropOpt, - // value: DTypePropOpt, + value: DTypePropOpt, actions: ActionsPropType, connected: BoolPropOpt, onChange: FuncPropOpt, @@ -149,7 +146,6 @@ export const MenuButtonComponent = ( return ( - - -