mirror of
https://github.com/tiqi-group/pydase.git
synced 2025-06-07 05:50: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;
|
docString: string;
|
||||||
isInstantUpdate: boolean;
|
isInstantUpdate: boolean;
|
||||||
unit?: string;
|
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
|
// 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) => {
|
export const NumberComponent = React.memo((props: NumberComponentProps) => {
|
||||||
const { name, parent_path, readOnly, docString, isInstantUpdate, unit } = props;
|
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);
|
const renderCount = useRef(0);
|
||||||
// Create a state for the cursor position
|
// Create a state for the cursor position
|
||||||
const [cursorPosition, setCursorPosition] = useState(null);
|
const [cursorPosition, setCursorPosition] = useState(null);
|
||||||
@ -199,7 +214,7 @@ export const NumberComponent = React.memo((props: NumberComponentProps) => {
|
|||||||
selectionEnd
|
selectionEnd
|
||||||
));
|
));
|
||||||
} else if (key === 'Enter' && !isInstantUpdate) {
|
} else if (key === 'Enter' && !isInstantUpdate) {
|
||||||
emit_update(name, parent_path, Number(newValue));
|
emitUpdate(name, parent_path, Number(newValue));
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
console.debug(key);
|
console.debug(key);
|
||||||
@ -208,7 +223,7 @@ export const NumberComponent = React.memo((props: NumberComponentProps) => {
|
|||||||
|
|
||||||
// Update the input value and maintain the cursor position
|
// Update the input value and maintain the cursor position
|
||||||
if (isInstantUpdate) {
|
if (isInstantUpdate) {
|
||||||
emit_update(name, parent_path, Number(newValue));
|
emitUpdate(name, parent_path, Number(newValue));
|
||||||
}
|
}
|
||||||
|
|
||||||
setInputString(newValue);
|
setInputString(newValue);
|
||||||
@ -220,20 +235,20 @@ export const NumberComponent = React.memo((props: NumberComponentProps) => {
|
|||||||
const handleBlur = () => {
|
const handleBlur = () => {
|
||||||
if (!isInstantUpdate) {
|
if (!isInstantUpdate) {
|
||||||
// If not in "instant update" mode, emit an update when the input field loses focus
|
// 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 (
|
return (
|
||||||
<div className={'numberComponent'} id={parent_path.concat(name)}>
|
<div className="numberComponent" id={parent_path.concat('.' + name)}>
|
||||||
{process.env.NODE_ENV === 'development' && (
|
{process.env.NODE_ENV === 'development' && showName && (
|
||||||
<p>Render count: {renderCount.current}</p>
|
<p>Render count: {renderCount.current}</p>
|
||||||
)}
|
)}
|
||||||
<DocStringComponent docString={docString} />
|
<DocStringComponent docString={docString} />
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="col-5 d-flex">
|
<div className="d-flex">
|
||||||
<InputGroup>
|
<InputGroup>
|
||||||
<InputGroup.Text>{name}</InputGroup.Text>
|
{showName && <InputGroup.Text>{name}</InputGroup.Text>}
|
||||||
<Form.Control
|
<Form.Control
|
||||||
type="text"
|
type="text"
|
||||||
value={inputString}
|
value={inputString}
|
||||||
|
@ -3,6 +3,7 @@ import { InputGroup, Form, Row, Col, Button, Collapse } from 'react-bootstrap';
|
|||||||
import { emit_update } from '../socket';
|
import { emit_update } from '../socket';
|
||||||
import { DocStringComponent } from './DocStringComponent';
|
import { DocStringComponent } from './DocStringComponent';
|
||||||
import { Slider } from '@mui/material';
|
import { Slider } from '@mui/material';
|
||||||
|
import { NumberComponent } from './NumberComponent';
|
||||||
|
|
||||||
interface SliderComponentProps {
|
interface SliderComponentProps {
|
||||||
name: string;
|
name: string;
|
||||||
@ -24,20 +25,38 @@ export const SliderComponent = React.memo((props: SliderComponentProps) => {
|
|||||||
renderCount.current++;
|
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 = (
|
const emitSliderUpdate = (
|
||||||
newNumber: number,
|
name: string,
|
||||||
|
parent_path: string,
|
||||||
|
value: number,
|
||||||
|
callback?: (ack: unknown) => void,
|
||||||
min: number = props.min,
|
min: number = props.min,
|
||||||
max: number = props.max,
|
max: number = props.max,
|
||||||
stepSize: number = props.stepSize
|
stepSize: number = props.stepSize
|
||||||
) => {
|
) => {
|
||||||
emit_update(name, parent_path, {
|
emit_update(
|
||||||
value: newNumber,
|
name,
|
||||||
min: min,
|
parent_path,
|
||||||
max: max,
|
{
|
||||||
step_size: stepSize
|
value: value,
|
||||||
});
|
min: min,
|
||||||
|
max: max,
|
||||||
|
step_size: stepSize
|
||||||
|
},
|
||||||
|
callback
|
||||||
|
);
|
||||||
};
|
};
|
||||||
const handleOnChange = (event, newNumber: number | number[]) => {
|
const handleOnChange = (event, newNumber: number | number[]) => {
|
||||||
// This will never be the case as we do not have a range slider. However, we should
|
// 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)) {
|
if (Array.isArray(newNumber)) {
|
||||||
newNumber = newNumber[0];
|
newNumber = newNumber[0];
|
||||||
}
|
}
|
||||||
socketEmit(newNumber, min, max, stepSize);
|
emitSliderUpdate(name, parent_path, newNumber);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleValueChange = (newValue: number, valueType: string) => {
|
const handleValueChange = (newValue: number, valueType: string) => {
|
||||||
switch (valueType) {
|
switch (valueType) {
|
||||||
case 'min':
|
case 'min':
|
||||||
socketEmit(value, newValue, max, stepSize);
|
emitSliderUpdate(name, parent_path, value, undefined, newValue);
|
||||||
break;
|
break;
|
||||||
case 'max':
|
case 'max':
|
||||||
socketEmit(value, min, newValue, stepSize);
|
emitSliderUpdate(name, parent_path, value, undefined, min, newValue);
|
||||||
break;
|
break;
|
||||||
case 'stepSize':
|
case 'stepSize':
|
||||||
socketEmit(value, min, max, newValue);
|
emitSliderUpdate(name, parent_path, value, undefined, min, max, newValue);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -65,24 +84,21 @@ export const SliderComponent = React.memo((props: SliderComponentProps) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={'sliderComponent'} id={parent_path.concat('.' + name)}>
|
<div className="sliderComponent" id={parent_path.concat('.' + name)}>
|
||||||
{process.env.NODE_ENV === 'development' && (
|
{process.env.NODE_ENV === 'development' && (
|
||||||
<p>Render count: {renderCount.current}</p>
|
<p>Render count: {renderCount.current}</p>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<DocStringComponent docString={docString} />
|
<DocStringComponent docString={docString} />
|
||||||
<Row>
|
<Row>
|
||||||
<Col className="col-5 d-flex align-items-center">
|
<Col xs="auto">
|
||||||
<InputGroup.Text
|
<InputGroup.Text>{name}</InputGroup.Text>
|
||||||
// style={{ height: '80px' }}
|
</Col>
|
||||||
>
|
<Col xs="5">
|
||||||
{name}
|
|
||||||
</InputGroup.Text>
|
|
||||||
{/* <Form.Group> */}
|
|
||||||
<Slider
|
<Slider
|
||||||
style={{ flex: 1, margin: '0px 0px 5px 10px' }}
|
style={{ margin: '0px 0px 10px 0px' }}
|
||||||
aria-label="Always visible"
|
aria-label="Always visible"
|
||||||
valueLabelDisplay="on"
|
// valueLabelDisplay="on"
|
||||||
disabled={readOnly}
|
disabled={readOnly}
|
||||||
value={value}
|
value={value}
|
||||||
onChange={(event, newNumber) => handleOnChange(event, newNumber)}
|
onChange={(event, newNumber) => handleOnChange(event, newNumber)}
|
||||||
@ -94,14 +110,19 @@ export const SliderComponent = React.memo((props: SliderComponentProps) => {
|
|||||||
{ value: max, label: `${max}` }
|
{ value: max, label: `${max}` }
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
{/* <Form.Control
|
</Col>
|
||||||
type="text"
|
<Col xs={4}>
|
||||||
value={value}
|
<NumberComponent
|
||||||
name={name}
|
isInstantUpdate={isInstantUpdate}
|
||||||
disabled={true}
|
parent_path={parent_path}
|
||||||
style={{ flex: 1, margin: '5px 0px 0px 10px' }}
|
name={name}
|
||||||
/> */}
|
docString=""
|
||||||
{/* </Form.Group> */}
|
readOnly={readOnly}
|
||||||
|
type="float"
|
||||||
|
value={value}
|
||||||
|
showName={false}
|
||||||
|
customEmitUpdate={emitSliderUpdate}
|
||||||
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<Row xs="auto">
|
<Row xs="auto">
|
||||||
|
Loading…
x
Reference in New Issue
Block a user