feat: adding NumberComponent to SliderComponent

This commit is contained in:
Mose Müller 2023-08-08 15:52:31 +02:00
parent b8b503b3d6
commit 32ecc9520f
2 changed files with 74 additions and 38 deletions

View File

@ -15,6 +15,13 @@ interface NumberComponentProps {
docString: string;
isInstantUpdate: boolean;
unit?: string;
showName?: boolean;
customEmitUpdate?: (
name: string,
parent_path: string,
value: number,
callback?: (ack: unknown) => void
) => void;
}
// TODO: highlight the digit that is being changed by setting both selectionStart and
@ -102,6 +109,14 @@ const handleDeleteKey = (
export const NumberComponent = React.memo((props: NumberComponentProps) => {
const { name, parent_path, readOnly, docString, isInstantUpdate, unit } = props;
// Whether to show the name infront of the component (false if used with a slider)
const showName = props.showName !== undefined ? props.showName : true;
// If emitUpdate is passed, use this instead of the emit_update from the socket
// Also used when used with a slider
const emitUpdate =
props.customEmitUpdate !== undefined ? props.customEmitUpdate : emit_update;
const renderCount = useRef(0);
// Create a state for the cursor position
const [cursorPosition, setCursorPosition] = useState(null);
@ -199,7 +214,7 @@ export const NumberComponent = React.memo((props: NumberComponentProps) => {
selectionEnd
));
} else if (key === 'Enter' && !isInstantUpdate) {
emit_update(name, parent_path, Number(newValue));
emitUpdate(name, parent_path, Number(newValue));
return;
} else {
console.debug(key);
@ -208,7 +223,7 @@ export const NumberComponent = React.memo((props: NumberComponentProps) => {
// Update the input value and maintain the cursor position
if (isInstantUpdate) {
emit_update(name, parent_path, Number(newValue));
emitUpdate(name, parent_path, Number(newValue));
}
setInputString(newValue);
@ -220,20 +235,20 @@ export const NumberComponent = React.memo((props: NumberComponentProps) => {
const handleBlur = () => {
if (!isInstantUpdate) {
// If not in "instant update" mode, emit an update when the input field loses focus
emit_update(name, parent_path, Number(inputString));
emitUpdate(name, parent_path, Number(inputString));
}
};
return (
<div className={'numberComponent'} id={parent_path.concat(name)}>
{process.env.NODE_ENV === 'development' && (
<div className="numberComponent" id={parent_path.concat('.' + name)}>
{process.env.NODE_ENV === 'development' && showName && (
<p>Render count: {renderCount.current}</p>
)}
<DocStringComponent docString={docString} />
<div className="row">
<div className="col-5 d-flex">
<div className="d-flex">
<InputGroup>
<InputGroup.Text>{name}</InputGroup.Text>
{showName && <InputGroup.Text>{name}</InputGroup.Text>}
<Form.Control
type="text"
value={inputString}

View File

@ -3,6 +3,7 @@ import { InputGroup, Form, Row, Col, Button, Collapse } from 'react-bootstrap';
import { emit_update } from '../socket';
import { DocStringComponent } from './DocStringComponent';
import { Slider } from '@mui/material';
import { NumberComponent } from './NumberComponent';
interface SliderComponentProps {
name: string;
@ -24,20 +25,38 @@ export const SliderComponent = React.memo((props: SliderComponentProps) => {
renderCount.current++;
});
const { name, parent_path, value, min, max, stepSize, readOnly, docString } = props;
const {
name,
parent_path,
value,
min,
max,
stepSize,
readOnly,
docString,
isInstantUpdate
} = props;
const socketEmit = (
newNumber: number,
const emitSliderUpdate = (
name: string,
parent_path: string,
value: number,
callback?: (ack: unknown) => void,
min: number = props.min,
max: number = props.max,
stepSize: number = props.stepSize
) => {
emit_update(name, parent_path, {
value: newNumber,
min: min,
max: max,
step_size: stepSize
});
emit_update(
name,
parent_path,
{
value: value,
min: min,
max: max,
step_size: stepSize
},
callback
);
};
const handleOnChange = (event, newNumber: number | number[]) => {
// This will never be the case as we do not have a range slider. However, we should
@ -45,19 +64,19 @@ export const SliderComponent = React.memo((props: SliderComponentProps) => {
if (Array.isArray(newNumber)) {
newNumber = newNumber[0];
}
socketEmit(newNumber, min, max, stepSize);
emitSliderUpdate(name, parent_path, newNumber);
};
const handleValueChange = (newValue: number, valueType: string) => {
switch (valueType) {
case 'min':
socketEmit(value, newValue, max, stepSize);
emitSliderUpdate(name, parent_path, value, undefined, newValue);
break;
case 'max':
socketEmit(value, min, newValue, stepSize);
emitSliderUpdate(name, parent_path, value, undefined, min, newValue);
break;
case 'stepSize':
socketEmit(value, min, max, newValue);
emitSliderUpdate(name, parent_path, value, undefined, min, max, newValue);
break;
default:
break;
@ -65,24 +84,21 @@ export const SliderComponent = React.memo((props: SliderComponentProps) => {
};
return (
<div className={'sliderComponent'} id={parent_path.concat('.' + name)}>
<div className="sliderComponent" id={parent_path.concat('.' + name)}>
{process.env.NODE_ENV === 'development' && (
<p>Render count: {renderCount.current}</p>
)}
<DocStringComponent docString={docString} />
<Row>
<Col className="col-5 d-flex align-items-center">
<InputGroup.Text
// style={{ height: '80px' }}
>
{name}
</InputGroup.Text>
{/* <Form.Group> */}
<Col xs="auto">
<InputGroup.Text>{name}</InputGroup.Text>
</Col>
<Col xs="5">
<Slider
style={{ flex: 1, margin: '0px 0px 5px 10px' }}
style={{ margin: '0px 0px 10px 0px' }}
aria-label="Always visible"
valueLabelDisplay="on"
// valueLabelDisplay="on"
disabled={readOnly}
value={value}
onChange={(event, newNumber) => handleOnChange(event, newNumber)}
@ -94,14 +110,19 @@ export const SliderComponent = React.memo((props: SliderComponentProps) => {
{ value: max, label: `${max}` }
]}
/>
{/* <Form.Control
type="text"
value={value}
name={name}
disabled={true}
style={{ flex: 1, margin: '5px 0px 0px 10px' }}
/> */}
{/* </Form.Group> */}
</Col>
<Col xs={4}>
<NumberComponent
isInstantUpdate={isInstantUpdate}
parent_path={parent_path}
name={name}
docString=""
readOnly={readOnly}
type="float"
value={value}
showName={false}
customEmitUpdate={emitSliderUpdate}
/>
</Col>
</Row>
<Row xs="auto">