import React, { useEffect, useState } from 'react';
|
import { useForm, Controller } from 'react-hook-form';
|
import {
|
Box,
|
Grid,
|
Typography,
|
TextField,
|
Slider,
|
Button,
|
Select,
|
MenuItem,
|
InputLabel,
|
FormControl,
|
Stack,
|
Divider,
|
} from '@mui/material';
|
import MuiInput from '@mui/material/Input';
|
import { useTranslate } from 'react-admin';
|
import * as Tool from '../tool';
|
import ConfirmButton from '../../page/components/ConfirmButton';
|
import CopyDrawer from './CopyDrawer';
|
|
const MapSettings = (props) => {
|
const { sprite, setSpriteSettings, onSubmit, width, lastCopiedSprites, setLastCopiedSprites } = props;
|
const translate = useTranslate();
|
const [copyVisible, setCopyVisible] = useState(false);
|
|
const { control, handleSubmit, reset, watch } = useForm({
|
defaultValues: {
|
x: sprite?.position?.x || 0,
|
y: sprite?.position?.y || 0,
|
scaleX: sprite?.scale?.x || 1,
|
scaleY: sprite?.scale?.y || 1,
|
rotation: (sprite?.rotation * 180) / Math.PI || 0,
|
copyDirection: 'right',
|
copyCount: 1,
|
},
|
});
|
|
const watchAllFields = watch();
|
|
useEffect(() => {
|
if (sprite) {
|
setCopyVisible(false);
|
reset({
|
x: sprite?.position.x,
|
y: sprite?.position.y,
|
scaleX: sprite?.scale.x,
|
scaleY: sprite?.scale.y,
|
rotation: (sprite?.rotation * 180) / Math.PI,
|
});
|
}
|
}, [sprite, reset]);
|
|
const updateSprite = (data) => {
|
if (sprite) {
|
sprite.position.x = data.x;
|
sprite.position.y = data.y;
|
sprite.scale.x = data.scaleX;
|
sprite.scale.y = data.scaleY;
|
sprite.rotation = (data.rotation * Math.PI) / 180;
|
}
|
};
|
|
const onFormSubmit = (data) => {
|
updateSprite(data);
|
if (onSubmit) {
|
onSubmit(data);
|
}
|
};
|
|
return (
|
<>
|
<Box component="form" onSubmit={handleSubmit(onFormSubmit)} noValidate sx={{ mt: 0 }}>
|
<Grid container spacing={1.4}>
|
{/* position */}
|
<Grid item xs={12}>
|
<Typography variant="inherit">
|
{translate('page.map.settings.map.base.position')}
|
</Typography>
|
</Grid>
|
<Grid item xs={6} pt={0} sx={{
|
paddingTop: '8px !important',
|
}}>
|
<Controller
|
name="x"
|
control={control}
|
render={({ field }) => (
|
<TextField
|
{...field}
|
label="X"
|
type="number"
|
fullWidth
|
onChange={(e) => {
|
const value = parseFloat(e.target.value);
|
field.onChange(e);
|
if (!isNaN(value)) {
|
updateSprite({ ...watchAllFields, x: value });
|
}
|
}}
|
/>
|
)}
|
/>
|
</Grid>
|
<Grid item xs={6} sx={{
|
paddingTop: '8px !important',
|
}}>
|
<Controller
|
name="y"
|
control={control}
|
render={({ field }) => (
|
<TextField
|
{...field}
|
label="Y"
|
type="number"
|
fullWidth
|
onChange={(e) => {
|
const value = parseFloat(e.target.value);
|
field.onChange(e);
|
if (!isNaN(value)) {
|
updateSprite({ ...watchAllFields, y: value });
|
}
|
}}
|
/>
|
)}
|
/>
|
</Grid>
|
|
{/* scale */}
|
<Grid item xs={12}>
|
<Typography variant="inherit">
|
{translate('page.map.settings.map.base.scale')}
|
</Typography>
|
</Grid>
|
<Grid item xs={6} sx={{
|
paddingTop: '8px !important',
|
}}>
|
<Controller
|
name="scaleX"
|
control={control}
|
render={({ field }) => (
|
<TextField
|
{...field}
|
label="X"
|
type="number"
|
fullWidth
|
inputProps={{ step: 0.1, min: 0.1, max: 10 }}
|
onChange={(e) => {
|
const value = parseFloat(e.target.value);
|
field.onChange(e);
|
if (!isNaN(value)) {
|
updateSprite({ ...watchAllFields, scaleX: value });
|
}
|
}}
|
/>
|
)}
|
/>
|
</Grid>
|
<Grid item xs={6} sx={{
|
paddingTop: '8px !important',
|
}}>
|
<Controller
|
name="scaleY"
|
control={control}
|
render={({ field }) => (
|
<TextField
|
{...field}
|
label="Y"
|
type="number"
|
fullWidth
|
inputProps={{ step: 0.1, min: 0.1, max: 10 }}
|
onChange={(e) => {
|
const value = parseFloat(e.target.value);
|
field.onChange(e);
|
if (!isNaN(value)) {
|
updateSprite({ ...watchAllFields, scaleY: value });
|
}
|
}}
|
/>
|
)}
|
/>
|
</Grid>
|
|
{/* rotation */}
|
<Grid item xs={12}>
|
<Typography variant="inherit">
|
{translate('page.map.settings.map.base.rotation')}
|
</Typography>
|
</Grid>
|
<Grid item xs={12}>
|
<Box display="flex" alignItems="center">
|
<Box flex={1} mr={3}>
|
<Controller
|
name="rotation"
|
control={control}
|
render={({ field }) => (
|
<Slider
|
{...field}
|
// size="small"
|
min={0}
|
max={360}
|
step={1}
|
valueLabelDisplay="auto"
|
valueLabelFormat={(value) => `${value}°`}
|
onChange={(e, value) => {
|
field.onChange(value);
|
updateSprite({ ...watchAllFields, rotation: value });
|
}}
|
/>
|
)}
|
/>
|
</Box>
|
<Box >
|
<Controller
|
name="rotation"
|
control={control}
|
render={({ field }) => (
|
<MuiInput
|
{...field}
|
size="small"
|
value={field.value}
|
onChange={(e) => {
|
const value = e.target.value === '' ? 0 : Number(e.target.value);
|
if (!isNaN(value)) {
|
field.onChange(value);
|
updateSprite({ ...watchAllFields, rotation: value });
|
}
|
}}
|
onBlur={() => {
|
if (field.value < 0) {
|
field.onChange(0);
|
} else if (field.value > 360) {
|
field.onChange(360);
|
}
|
}}
|
inputProps={{
|
step: 1,
|
min: 0,
|
max: 360,
|
type: 'number',
|
'aria-labelledby': 'input-slider',
|
}}
|
/>
|
)}
|
/>
|
</Box>
|
</Box>
|
</Grid>
|
|
<Grid item xs={12}>
|
<Divider />
|
</Grid>
|
|
{/* copy */}
|
<Grid item xs={12}>
|
<Typography variant="inherit">
|
{translate('page.map.settings.map.copy.title')}
|
</Typography>
|
</Grid>
|
<Grid item xs={6} sx={{
|
paddingTop: '8px !important',
|
}}>
|
<Controller
|
name="copyDirection"
|
control={control}
|
render={({ field }) => (
|
<FormControl fullWidth>
|
<InputLabel>
|
{translate('page.map.settings.map.copy.direction')}
|
</InputLabel>
|
<Select
|
{...field}
|
label={translate('page.map.settings.map.copy.direction')}
|
>
|
<MenuItem value="left">
|
{translate('page.map.settings.map.copy.left')}
|
</MenuItem>
|
<MenuItem value="right">
|
{translate('page.map.settings.map.copy.right')}
|
</MenuItem>
|
<MenuItem value="up">
|
{translate('page.map.settings.map.copy.up')}
|
</MenuItem>
|
<MenuItem value="down">
|
{translate('page.map.settings.map.copy.down')}
|
</MenuItem>
|
</Select>
|
</FormControl>
|
)}
|
/>
|
</Grid>
|
<Grid item xs={6} sx={{
|
paddingTop: '8px !important',
|
}}>
|
<Controller
|
name="copyCount"
|
control={control}
|
render={({ field }) => (
|
<TextField
|
{...field}
|
label={translate('page.map.settings.map.copy.count')}
|
type="number"
|
fullWidth
|
inputProps={{ min: 1 }}
|
/>
|
)}
|
/>
|
</Grid>
|
<Grid item xs={12}>
|
<Stack direction="row" spacing={2}>
|
<Button variant="contained" color="primary" onClick={() => {
|
setCopyVisible(true);
|
}}>
|
{translate('page.map.settings.map.copy.execute')}
|
</Button>
|
<Button variant="text" color="primary" onClick={() => {
|
if (lastCopiedSprites && lastCopiedSprites.length > 0) {
|
lastCopiedSprites.forEach(copiedSprite => {
|
Tool.getMapContainer().removeChild(copiedSprite);
|
})
|
setLastCopiedSprites([]);
|
}
|
}}>
|
{translate('page.map.settings.map.copy.reverse')}
|
</Button>
|
</Stack>
|
</Grid>
|
|
<Grid item xs={12}>
|
<Divider />
|
</Grid>
|
|
{/* more */}
|
<Grid item xs={12}>
|
<Typography variant="inherit">
|
{translate('page.map.settings.map.more.title')}
|
</Typography>
|
</Grid>
|
<Grid item xs={12}>
|
<Stack direction="row" spacing={2}>
|
<Button variant="outlined" color="error" onClick={() => {
|
Tool.getMapContainer().removeChild(sprite);
|
setSpriteSettings(null);
|
Tool.removeSelectedEffect();
|
reset();
|
}}>
|
{translate('ra.action.delete')}
|
</Button>
|
{/* <ConfirmButton /> */}
|
</Stack>
|
</Grid>
|
</Grid>
|
</Box >
|
|
<CopyDrawer
|
open={copyVisible}
|
onCancel={() => {
|
setCopyVisible(false);
|
}}
|
width={width}
|
sprite={sprite}
|
value={{
|
copyDirect: watch('copyDirection'),
|
copyCount: watch('copyCount'),
|
}}
|
handleOnCopy={() => {
|
|
}}
|
setLastCopiedSprites={setLastCopiedSprites}
|
setSpriteSettings={setSpriteSettings}
|
/>
|
</>
|
);
|
};
|
|
export default MapSettings;
|