mirror of
https://github.com/tiqi-group/pydase.git
synced 2025-06-06 13:30:41 +02:00
feat: adding NumberComponent to SliderComponent
This commit is contained in:
parent
b8b503b3d6
commit
32ecc9520f
@ -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}
|
||||
|
@ -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">
|
||||
|
Loading…
x
Reference in New Issue
Block a user