| 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; |