Skip to content

Commit

Permalink
Refactor OneAxisTranslationControl
Browse files Browse the repository at this point in the history
  • Loading branch information
axelboc committed Oct 10, 2024
1 parent 6d613ea commit 54beaa8
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 139 deletions.
240 changes: 102 additions & 138 deletions ui/src/components/MotorInput/OneAxisTranslationControl.jsx
Original file line number Diff line number Diff line change
@@ -1,121 +1,80 @@
import React from 'react';
import { Button, Form, Popover } from 'react-bootstrap';
/* eslint-disable jsx-a11y/control-has-associated-label */
import React, { useEffect, useState } from 'react';
import { Button, Form } from 'react-bootstrap';

import { HW_STATE } from '../../constants';
import MotorInput from './MotorInput';
import './motor.css';
import styles from './OneAxisTranslationControl.module.css';

// eslint-disable-next-line react/no-unsafe
export default class OneAxisTranslationControl extends React.Component {
constructor(props) {
super(props);
this.state = { edited: false };
this.handleKey = this.handleKey.bind(this);
this.stepChange = this.stepChange.bind(this);
}
function OneAxisTranslationControl(props) {
const {
value,
state,
motorName,
step,
decimalPoints,
min,
max,
disabled,
save,
} = props;

/* eslint-enable react/no-set-state */
UNSAFE_componentWillReceiveProps(nextProps) {
if (nextProps.value && nextProps.value !== this.props.value) {
this.motorValue.value = nextProps.value.toFixed(this.props.decimalPoints);
this.motorValue.defaultValue = nextProps.value.toFixed(
this.props.decimalPoints,
);
this.setState({ edited: false });
}
}
const [inputValue, setInputValue] = useState(value.toFixed(decimalPoints));
const [isEdited, setEdited] = useState(false);

handleKey(e) {
e.preventDefault();
e.stopPropagation();
useEffect(() => {
setInputValue(value.toFixed(decimalPoints));
setEdited(false);
}, [value, decimalPoints]);

this.setState({ edited: true });
if (this.props.value) {
if (
[13, 38, 40].includes(e.keyCode) &&
this.props.state === HW_STATE.READY
) {
this.setState({ edited: false });
this.props.save(e.target.name, e.target.valueAsNumber);
this.motorValue.value = this.props.value.toFixed(
this.props.decimalPoints,
);
} else if (this.props.state === HW_STATE.BUSY) {
this.setState({ edited: false });
this.motorValue.value = this.props.value.toFixed(
this.props.decimalPoints,
);
function handleKey(evt) {
switch (evt.key) {
case 'ArrowUp': {
evt.preventDefault();
save(motorName, value + step);
break;
}
case 'ArrowDown': {
evt.preventDefault();
save(motorName, value - step);
break;
}
default:
}
}
/* eslint-enable react/no-set-state */

stepChange(name, step, operator) {
const { value } = this.props;
const newValue = value + step * operator;
this.props.save(name, newValue);
}
function handleSubmit(evt) {
evt.preventDefault();

const newValue = Number.parseFloat(inputValue);

renderMotorSettings() {
return (
<Popover title={<b>Sample alignment motors</b>}>
<div>
<MotorInput
save={this.props.save}
value={this.props.motors.sample_vertical.position}
saveStep={this.props.saveStep}
step={this.props.steps.sample_verticalStep}
motorName="sample_vertical"
label="Vertical"
suffix="mm"
decimalPoints="3"
state={this.props.motors.sample_vertical.state}
stop={this.props.stop}
disabled={this.props.motorsDisabled}
inplace
/>
<MotorInput
save={this.props.save}
value={this.props.motors.sample_horizontal.position}
saveStep={this.props.saveStep}
step={this.props.steps.sample_horizontalStep}
motorName="sample_horizontal"
label="Horizontal"
suffix="mm"
decimalPoints="3"
state={this.props.motors.sample_horizontal.state}
stop={this.props.stop}
disabled={this.props.motorsDisabled}
inplace
/>
</div>
</Popover>
);
if (!Number.isNaN(newValue)) {
save(motorName, newValue);
setEdited(false);
}
}

render() {
const { value, motorName, step, decimalPoints } = this.props;
const valueCropped = value ? value.toFixed(decimalPoints) : '';
return (
<div className={`${styles.root} arrow-control`}>
<Button
variant="outline-secondary"
style={{ marginRight: '2px' }}
className="arrow-small arrow-left"
disabled={state !== HW_STATE.READY || disabled}
onClick={() => save(motorName, value - 10 * step)}
>
<i className="fas fa-angle-double-left" />
</Button>
<Button
variant="outline-secondary"
className="arrow-small arrow-left"
disabled={state !== HW_STATE.READY || disabled}
onClick={() => save(motorName, value - step)}
>
<i className="fas fa-angle-left" />
</Button>

return (
<div className="arrow-control">
<Button
variant="outline-secondary"
style={{ marginRight: '2px' }}
className="arrow-small arrow-left"
disabled={this.props.state !== HW_STATE.READY || this.props.disabled}
onClick={() => this.stepChange(motorName, 10 * step, -1)}
>
<i className="fas fa-angle-double-left" />
</Button>
<Button
variant="outline-secondary"
className="arrow-small arrow-left"
disabled={this.props.state !== HW_STATE.READY || this.props.disabled}
onClick={() => this.stepChange(motorName, step, -1)}
>
<i className="fas fa-angle-left" />
</Button>
<form noValidate onSubmit={handleSubmit}>
<Form.Control
style={{
width: `${Number.parseFloat(decimalPoints) + 2}em`,
Expand All @@ -124,46 +83,51 @@ export default class OneAxisTranslationControl extends React.Component {
marginLeft: '5px',
marginRight: '5px',
}}
ref={(ref) => {
this.motorValue = ref;
}}
className={`${styles.input} rw-input`}
onKeyUp={this.handleKey}
name="value"
type="number"
max={this.props.max}
min={this.props.min}
max={max}
min={min}
step={step}
defaultValue={valueCropped}
name={motorName}
disabled={this.props.state !== HW_STATE.READY || this.props.disabled}
data-dirty={this.state.edited || undefined}
data-busy={this.props.state === HW_STATE.BUSY || undefined}
data-warning={this.props.state === HW_STATE.WARNING || undefined}
disabled={state !== HW_STATE.READY || disabled}
data-dirty={isEdited || undefined}
data-busy={state === HW_STATE.BUSY || undefined}
data-warning={state === HW_STATE.WARNING || undefined}
data-fault={
this.props.state === HW_STATE.UNKNOWN ||
this.props.state === HW_STATE.FAULT ||
this.props.state === HW_STATE.OFF ||
state === HW_STATE.UNKNOWN ||
state === HW_STATE.FAULT ||
state === HW_STATE.OFF ||
undefined
}
value={inputValue}
onChange={(evt) => {
setInputValue(evt.target.value);
setEdited(true);
}}
onKeyDown={handleKey}
/>
<Button
variant="outline-secondary"
className="arrow-small arrow-right"
disabled={this.props.state !== HW_STATE.READY || this.props.disabled}
onClick={() => this.stepChange(motorName, step, 1)}
>
<i className="fas fa-angle-right" />
</Button>
<Button
variant="outline-secondary"
style={{ marginLeft: '2px' }}
className="arrow-small arrow-right"
disabled={this.props.state !== HW_STATE.READY || this.props.disabled}
onClick={() => this.stepChange(motorName, 10 * step, 1)}
>
<i className="fas fa-angle-double-right" />
</Button>
</div>
);
}
<input type="submit" hidden /> {/* allow submit on Enter */}
</form>

<Button
variant="outline-secondary"
className="arrow-small arrow-right"
disabled={state !== HW_STATE.READY || disabled}
onClick={() => save(motorName, value + step)}
>
<i className="fas fa-angle-right" />
</Button>
<Button
variant="outline-secondary"
style={{ marginLeft: '2px' }}
className="arrow-small arrow-right"
disabled={state !== HW_STATE.READY || disabled}
onClick={() => save(motorName, value + 10 * step)}
>
<i className="fas fa-angle-double-right" />
</Button>
</div>
);
}

export default OneAxisTranslationControl;
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
.root {
display: flex;
align-items: center;
}

.input {
background-color: var(--hw-ready--bg) !important;
transition: background-color 100ms ease-in;
Expand All @@ -16,6 +21,6 @@
background-color: var(--hw-fault--bg) !important;
}

.input[data-edited] {
.input[data-dirty] {
background-color: var(--field-dirty--bg) !important;
}

0 comments on commit 54beaa8

Please sign in to comment.