qcast-front/src/hooks/roofcover/useRoofAllocationSetting.js

289 lines
8.7 KiB
JavaScript

import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'
import { canvasState, currentMenuState, currentObjectState } from '@/store/canvasAtom'
import { useEffect, useRef, useState } from 'react'
import { useSwal } from '@/hooks/useSwal'
import { usePolygon } from '@/hooks/usePolygon'
import { addedRoofsState, basicSettingState, roofDisplaySelector, roofMaterialsSelector, selectedRoofMaterialSelector } from '@/store/settingAtom'
import { usePopup } from '@/hooks/usePopup'
import { POLYGON_TYPE } from '@/common/common'
import { v4 as uuidv4 } from 'uuid'
import ActualSizeSetting from '@/components/floor-plan/modal/roofAllocation/ActualSizeSetting'
import { useMessage } from '@/hooks/useMessage'
import useMenu from '@/hooks/common/useMenu'
import { useCanvasMenu } from '@/hooks/common/useCanvasMenu'
import { menuTypeState } from '@/store/menuAtom'
import { useRoofFn } from '@/hooks/common/useRoofFn'
// 지붕면 할당
export function useRoofAllocationSetting(id) {
const canvas = useRecoilValue(canvasState)
const roofDisplay = useRecoilValue(roofDisplaySelector)
const { drawDirectionArrow, addLengthText, splitPolygonWithLines, splitPolygonWithSeparate } = usePolygon()
const [popupId, setPopupId] = useState(uuidv4())
const { addPopup, closePopup, closeAll } = usePopup()
const { getMessage } = useMessage()
const currentObject = useRecoilValue(currentObjectState)
const { swalFire } = useSwal()
const { setMenuNumber } = useCanvasMenu()
const setMenuType = useSetRecoilState(menuTypeState)
const roofMaterials = useRecoilValue(roofMaterialsSelector)
const selectedRoofMaterial = useRecoilValue(selectedRoofMaterialSelector)
const [basicSetting, setBasicSetting] = useRecoilState(basicSettingState)
const [currentRoofMaterial, setCurrentRoofMaterial] = useState(roofMaterials[0]) // 팝업 내 기준 지붕재
const [roofList, setRoofList] = useRecoilState(addedRoofsState) // 배치면 초기설정에서 선택한 지붕재 배열
const [editingLines, setEditingLines] = useState([])
const isFirstRef = useRef(0)
const { setSurfaceShapePattern } = useRoofFn()
useEffect(() => {
const roofBases = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF) // roofPolygon.innerLines
roofBases.forEach((roof) => {
roof.innerLines.forEach((line) => {
if (!line.attributes.actualSize || line.attributes?.actualSize === 0) {
line.set({
strokeWidth: 4,
stroke: 'black',
selectable: true,
})
}
if (editingLines.includes(line)) {
line.set({
strokeWidth: 2,
stroke: 'black',
selectable: true,
})
}
})
})
if (currentObject && currentObject.name && ['auxiliaryLine', 'ridge', 'hip'].includes(currentObject.name)) {
currentObject.set({
strokeWidth: 4,
stroke: '#EA10AC',
})
}
}, [currentObject])
useEffect(() => {
// canvas.getObjects().filter((obj) => obj.type === 'QLine')
const roofBases = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF)
if (roofBases.length === 0) {
swalFire({ text: '할당할 지붕이 없습니다.' })
closePopup(id)
}
}, [])
const onAddRoofMaterial = () => {
if (roofList.length >= 4) {
swalFire({ type: 'alert', icon: 'error', text: getMessage('지붕재는 4개까지 선택 가능합니다.') })
return
}
setRoofList([...roofList, { ...currentRoofMaterial, selected: false, id: currentRoofMaterial.roofMatlCd, name: currentRoofMaterial.roofMatlNm }])
}
const onDeleteRoofMaterial = (idx) => {
setRoofList([...roofList.filter((_, index) => index !== idx)])
}
const { handleMenu } = useMenu()
const [currentMenu, setCurrentMenu] = useRecoilState(currentMenuState)
// 선택한 지붕재로 할당
const handleSave = () => {
// 모두 actualSize 있으면 바로 적용 없으면 actualSize 설정
if (checkInnerLines()) {
addPopup(popupId, 1, <ActualSizeSetting id={popupId} />)
} else {
apply()
}
}
// 지붕재 오른쪽 마우스 클릭 후 단일로 지붕재 변경 필요한 경우
const handleSaveContext = () => {
const selectedRoofMaterial = roofList.find((roof) => roof.selected)
setSurfaceShapePattern(currentObject, roofDisplay.column, false, selectedRoofMaterial)
closeAll()
}
const handleAlloc = () => {
if (!checkInnerLines()) {
apply()
} else {
swalFire({
type: 'alert',
icon: 'error',
text: getMessage('실제치수를 입력해 주세요.'),
})
}
}
const checkInnerLines = () => {
const roofBases = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF) // roofPolygon.innerLines
let result = false
roofBases.forEach((roof) => {
if (roof.separatePolygon.length === 0) {
roof.innerLines.forEach((line) => {
if (!line.attributes.actualSize || line.attributes?.actualSize === 0) {
line.set({
strokeWidth: 4,
stroke: 'black',
selectable: true,
})
result = true
}
})
}
})
if (result) canvas?.renderAll()
return result
}
const apply = () => {
const roofBases = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF && !obj.isFixed)
const wallLines = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.WALL)
roofBases.forEach((roofBase) => {
try {
if (roofBase.separatePolygon.length > 0) {
splitPolygonWithSeparate(roofBase.separatePolygon)
} else {
splitPolygonWithLines(roofBase)
}
} catch (e) {
return
}
roofBase.innerLines.forEach((line) => {
canvas.remove(line)
})
canvas.remove(roofBase)
})
wallLines.forEach((wallLine) => {
canvas.remove(wallLine)
})
setBasicSetting((prev) => {
return {
...prev,
selectedRoofMaterial: roofList.find((roof) => roof.selected),
}
})
setRoofList(roofList)
const roofs = canvas.getObjects().filter((obj) => obj.name === 'roof')
roofs.forEach((roof) => {
if (roof.isFixed) return
roof.set({
isFixed: true,
})
setSurfaceShapePattern(roof, roofDisplay.column)
drawDirectionArrow(roof)
})
const removeTargets = canvas.getObjects().filter((obj) => obj.name === 'outerLinePoint' || obj.name === 'outerLine')
removeTargets.forEach((obj) => {
canvas.remove(obj)
})
setEditingLines([])
closeAll()
setMenuNumber(3)
setMenuType('surface')
}
const setLineSize = (id, size) => {
const roofBases = canvas.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF)
roofBases.forEach((roof) => {
roof.innerLines.forEach((line) => {
if (id === line.id) {
setEditingLines([...editingLines.filter((editLine) => editLine.id !== line.id), line])
line.attributes.actualSize = size
line.set({
strokeWidth: 2,
stroke: 'black',
})
}
})
})
canvas?.renderAll()
}
// 지붕재 변경
const handleChangeRoofMaterial = (value, index) => {
if (isFirstRef.current === 0) {
isFirstRef.current++
return
}
const selectedRoofMaterial = roofMaterials.find((roof) => roof.roofMatlCd === value.id)
const newRoofList = roofList.map((roof, idx) => {
if (idx === index) {
return { ...selectedRoofMaterial }
}
return roof
})
setRoofList(newRoofList)
}
// 기본 지붕재 radio값 변경
const handleDefaultRoofMaterial = (index) => {
const newRoofList = roofList.map((roof, idx) => {
return { ...roof, selected: idx === index }
})
setRoofList(newRoofList)
}
// 서까래 변경
const handleChangeRaft = (e, index) => {
const raftValue = e.value
const newRoofList = roofList.map((roof, idx) => {
if (idx === index) {
return { ...roof, raft: raftValue }
}
return roof
})
setRoofList(newRoofList)
}
const handleChangeLayout = (layoutValue, index) => {
const newRoofList = roofList.map((roof, idx) => {
if (idx === index) {
return { ...roof, layout: layoutValue }
}
return roof
})
setRoofList(newRoofList)
}
return {
handleSave,
onAddRoofMaterial,
onDeleteRoofMaterial,
handleAlloc,
setLineSize,
roofMaterials,
selectedRoofMaterial,
basicSetting,
setBasicSetting,
currentRoofMaterial,
setCurrentRoofMaterial,
roofList,
handleDefaultRoofMaterial,
handleChangeRoofMaterial,
handleChangeRaft,
handleChangeLayout,
handleSaveContext,
}
}