Merge branch 'qcast-pub' into dev

This commit is contained in:
minsik 2024-10-31 14:31:59 +09:00
commit 8bd3834b72
8 changed files with 57 additions and 21 deletions

View File

@ -13,7 +13,7 @@ export default function AuxiliarySize(props) {
<WithDraggable isShow={true} pos={pos}> <WithDraggable isShow={true} pos={pos}>
<div className={`modal-pop-wrap xm`}> <div className={`modal-pop-wrap xm`}>
<div className="modal-head"> <div className="modal-head">
<h1 className="title">補助線サイズ変更 </h1> <h1 className="title">{getMessage('modal.auxiliary.size.edit')} </h1>
<button className="modal-close" onClick={() => closePopup(id)}> <button className="modal-close" onClick={() => closePopup(id)}>
닫기 닫기
</button> </button>
@ -22,7 +22,7 @@ export default function AuxiliarySize(props) {
<div className="discrimination-box mb10"> <div className="discrimination-box mb10">
<div className="d-check-radio pop mb10"> <div className="d-check-radio pop mb10">
<input type="radio" name="radio01" id="ra01" /> <input type="radio" name="radio01" id="ra01" />
<label htmlFor="ra01">1支店</label> <label htmlFor="ra01">1{getMessage('modal.auxiliary.size.edit.point')}</label>
</div> </div>
<div className="outline-form mb15"> <div className="outline-form mb15">
<div className="input-grid mr5" style={{ flex: '1 1 auto' }}> <div className="input-grid mr5" style={{ flex: '1 1 auto' }}>
@ -31,7 +31,7 @@ export default function AuxiliarySize(props) {
<span className="thin">mm</span> <span className="thin">mm</span>
</div> </div>
<div className="outline-form"> <div className="outline-form">
<span style={{ width: 'auto' }}>長さ</span> <span style={{ width: 'auto' }}>{getMessage('length')}</span>
<div className="input-grid mr5"> <div className="input-grid mr5">
<input type="text" className="input-origin block" defaultValue={100} /> <input type="text" className="input-origin block" defaultValue={100} />
</div> </div>
@ -41,7 +41,7 @@ export default function AuxiliarySize(props) {
<div className="discrimination-box "> <div className="discrimination-box ">
<div className="d-check-radio pop mb10"> <div className="d-check-radio pop mb10">
<input type="radio" name="radio01" id="ra02" /> <input type="radio" name="radio01" id="ra02" />
<label htmlFor="ra02">2支店</label> <label htmlFor="ra02">2{getMessage('modal.auxiliary.size.edit.point')}</label>
</div> </div>
<div className="outline-form mb15"> <div className="outline-form mb15">
<div className="input-grid mr5" style={{ flex: '1 1 auto' }}> <div className="input-grid mr5" style={{ flex: '1 1 auto' }}>
@ -50,7 +50,7 @@ export default function AuxiliarySize(props) {
<span className="thin">mm</span> <span className="thin">mm</span>
</div> </div>
<div className="outline-form"> <div className="outline-form">
<span style={{ width: 'auto' }}>長さ</span> <span style={{ width: 'auto' }}>{getMessage('length')}</span>
<div className="input-grid mr5"> <div className="input-grid mr5">
<input type="text" className="input-origin block" defaultValue={100} /> <input type="text" className="input-origin block" defaultValue={100} />
</div> </div>
@ -58,7 +58,7 @@ export default function AuxiliarySize(props) {
</div> </div>
</div> </div>
<div className="grid-btn-wrap"> <div className="grid-btn-wrap">
<button className="btn-frame modal act">保存</button> <button className="btn-frame modal act">{getMessage('modal.common.save')}</button>
</div> </div>
</div> </div>
</div> </div>

View File

@ -19,7 +19,8 @@ export default function ObjectSetting({ id, pos = { x: 50, y: 230 } }) {
const canvas = useRecoilValue(canvasState) const canvas = useRecoilValue(canvasState)
const [buttonAct, setButtonAct] = useState(1) const [buttonAct, setButtonAct] = useState(1)
const { swalFire } = useSwal() const { swalFire } = useSwal()
const { applyOpeningAndShadow, applyDormers } = useObjectBatch() const [isHidden, setIsHidden] = useState(false)
const { applyOpeningAndShadow, applyDormers } = useObjectBatch({ isHidden, setIsHidden })
const { closePopup } = usePopup() const { closePopup } = usePopup()
const surfaceShapePolygons = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF) const surfaceShapePolygons = canvas?.getObjects().filter((obj) => obj.name === POLYGON_TYPE.ROOF)
@ -58,6 +59,7 @@ export default function ObjectSetting({ id, pos = { x: 50, y: 230 } }) {
} }
//, //,
setIsHidden(true)
if (buttonAct === 1 || buttonAct === 2) { if (buttonAct === 1 || buttonAct === 2) {
applyOpeningAndShadow(objectPlacement, buttonAct, surfaceShapePolygons) applyOpeningAndShadow(objectPlacement, buttonAct, surfaceShapePolygons)
} else { } else {
@ -71,9 +73,10 @@ export default function ObjectSetting({ id, pos = { x: 50, y: 230 } }) {
{ id: 3, name: getMessage('modal.object.setting.type.triangle.dormer') }, { id: 3, name: getMessage('modal.object.setting.type.triangle.dormer') },
{ id: 4, name: getMessage('modal.object.setting.type.pentagon.dormer') }, { id: 4, name: getMessage('modal.object.setting.type.pentagon.dormer') },
] ]
return ( return (
<WithDraggable isShow={true} pos={pos}> <WithDraggable isShow={true} pos={pos}>
<div className={`modal-pop-wrap lrr`}> <div className={`modal-pop-wrap lrr`} style={{ visibility: isHidden ? 'hidden' : 'visible' }}>
<div className="modal-head"> <div className="modal-head">
<h1 className="title">{getMessage('plan.menu.placement.surface.object')} </h1> <h1 className="title">{getMessage('plan.menu.placement.surface.object')} </h1>
<button className="modal-close" onClick={() => closePopup(id)}> <button className="modal-close" onClick={() => closePopup(id)}>

View File

@ -4,13 +4,13 @@ import { useRecoilValue } from 'recoil'
import { canvasState } from '@/store/canvasAtom' import { canvasState } from '@/store/canvasAtom'
import { BATCH_TYPE, INPUT_TYPE } from '@/common/common' import { BATCH_TYPE, INPUT_TYPE } from '@/common/common'
import { useEvent } from '@/hooks/useEvent' import { useEvent } from '@/hooks/useEvent'
import { pointsToTurfPolygon, polygonToTurfPolygon, rectToPolygon, triangleToPolygon, setSurfaceShapePattern } from '@/util/canvas-util' import { pointsToTurfPolygon, polygonToTurfPolygon, rectToPolygon, setSurfaceShapePattern, triangleToPolygon } from '@/util/canvas-util'
import { useSwal } from '@/hooks/useSwal' import { useSwal } from '@/hooks/useSwal'
import * as turf from '@turf/turf' import * as turf from '@turf/turf'
import { usePolygon } from '@/hooks/usePolygon' import { usePolygon } from '@/hooks/usePolygon'
import { QPolygon } from '@/components/fabric/QPolygon' import { QPolygon } from '@/components/fabric/QPolygon'
export function useObjectBatch() { export function useObjectBatch({ isHidden, setIsHidden }) {
const { getMessage } = useMessage() const { getMessage } = useMessage()
const canvas = useRecoilValue(canvasState) const canvas = useRecoilValue(canvasState)
const { addCanvasMouseEventListener, initEvent } = useEvent() const { addCanvasMouseEventListener, initEvent } = useEvent()
@ -21,12 +21,12 @@ export function useObjectBatch() {
const selectedType = objectPlacement.typeRef.current.find((radio) => radio.checked).value const selectedType = objectPlacement.typeRef.current.find((radio) => radio.checked).value
const isCrossChecked = buttonAct === 1 ? objectPlacement.isCrossRef.current.checked : false const isCrossChecked = buttonAct === 1 ? objectPlacement.isCrossRef.current.checked : false
const objName = buttonAct === 1 ? BATCH_TYPE.OPENING : BATCH_TYPE.SHADOW const objName = buttonAct === 1 ? BATCH_TYPE.OPENING : BATCH_TYPE.SHADOW
const objTempName = buttonAct === 1 ? BATCH_TYPE.OPENING_TEMP : BATCH_TYPE.SHADOW_TEMP
const objTempName = buttonAct === 1 ? BATCH_TYPE.OPENING_TEMP : BATCH_TYPE.SHADOW_TEMP
let rect, isDown, origX, origY let rect, isDown, origX, origY
let selectedSurface let selectedSurface
//프리입력 //프리입력
console.log('useObjectBatch', isHidden)
if (selectedType === INPUT_TYPE.FREE) { if (selectedType === INPUT_TYPE.FREE) {
addCanvasMouseEventListener('mouse:down', (e) => { addCanvasMouseEventListener('mouse:down', (e) => {
isDown = true isDown = true
@ -41,6 +41,7 @@ export function useObjectBatch() {
if (!selectedSurface) { if (!selectedSurface) {
swalFire({ text: '지붕안에 그려야해요', icon: 'error' }) swalFire({ text: '지붕안에 그려야해요', icon: 'error' })
initEvent() //이벤트 초기화 initEvent() //이벤트 초기화
if (setIsHidden) setIsHidden(false)
return return
} }
@ -117,6 +118,8 @@ export function useObjectBatch() {
rect.set({ name: objName }) rect.set({ name: objName })
rect.setCoords() rect.setCoords()
initEvent() initEvent()
if (setIsHidden) setIsHidden(false)
} }
}) })
} else if (selectedType === INPUT_TYPE.DIMENSION) { } else if (selectedType === INPUT_TYPE.DIMENSION) {
@ -196,6 +199,7 @@ export function useObjectBatch() {
rect.set({ name: objName }) rect.set({ name: objName })
rect.setCoords() rect.setCoords()
initEvent() initEvent()
if (setIsHidden) setIsHidden(false)
} }
}) })
} }
@ -399,6 +403,7 @@ export function useObjectBatch() {
isDown = false isDown = false
initEvent() initEvent()
if (setIsHidden) setIsHidden(false)
} }
}) })
} else if (buttonAct === 4) { } else if (buttonAct === 4) {
@ -494,6 +499,7 @@ export function useObjectBatch() {
//지붕 밖으로 그렸을때 //지붕 밖으로 그렸을때
if (!turf.booleanWithin(pentagonPolygon, selectedSurfacePolygon)) { if (!turf.booleanWithin(pentagonPolygon, selectedSurfacePolygon)) {
swalFire({ text: '개구를 배치할 수 없습니다.', icon: 'error' }) swalFire({ text: '개구를 배치할 수 없습니다.', icon: 'error' })
//일단 지워 //일단 지워
deleteTempObjects() deleteTempObjects()
return return
@ -574,6 +580,7 @@ export function useObjectBatch() {
isDown = false isDown = false
initEvent() initEvent()
if (setIsHidden) setIsHidden(false)
} }
}) })
} }
@ -591,6 +598,7 @@ export function useObjectBatch() {
) )
canvas?.remove(...deleteTarget) canvas?.remove(...deleteTarget)
initEvent() //이벤트 초기화 initEvent() //이벤트 초기화
if (setIsHidden) setIsHidden(false)
} }
const splitDormerTriangle = (triangle, direction) => { const splitDormerTriangle = (triangle, direction) => {
@ -690,28 +698,40 @@ export function useObjectBatch() {
leftPoints = [ leftPoints = [
{ x: points[0].x, y: points[0].y }, { x: points[0].x, y: points[0].y },
{ x: points[0].x - (points[1].y - points[0].y), y: points[0].y - (points[0].x - points[1].x) }, { x: points[0].x - (points[1].y - points[0].y), y: points[0].y - (points[0].x - points[1].x) },
{ x: points[0].x - (points[1].y - points[0].y) - (points[2].y - points[1].y), y: points[0].y - (points[0].x - points[1].x) }, {
x: points[0].x - (points[1].y - points[0].y) - (points[2].y - points[1].y),
y: points[0].y - (points[0].x - points[1].x),
},
{ x: points[0].x - (points[1].y - points[0].y) - (points[2].y - points[1].y), y: points[0].y }, { x: points[0].x - (points[1].y - points[0].y) - (points[2].y - points[1].y), y: points[0].y },
] ]
rightPoints = [ rightPoints = [
{ x: points[0].x, y: points[0].y }, { x: points[0].x, y: points[0].y },
{ x: points[0].x - (points[1].y - points[0].y), y: points[0].y + (points[0].x - points[1].x) }, { x: points[0].x - (points[1].y - points[0].y), y: points[0].y + (points[0].x - points[1].x) },
{ x: points[0].x - (points[1].y - points[0].y) - (points[2].y - points[1].y), y: points[0].y + (points[0].x - points[1].x) }, {
x: points[0].x - (points[1].y - points[0].y) - (points[2].y - points[1].y),
y: points[0].y + (points[0].x - points[1].x),
},
{ x: points[0].x - (points[1].y - points[0].y) - (points[2].y - points[1].y), y: points[0].y }, { x: points[0].x - (points[1].y - points[0].y) - (points[2].y - points[1].y), y: points[0].y },
] ]
} else if (direction === 'right') { } else if (direction === 'right') {
leftPoints = [ leftPoints = [
{ x: points[0].x, y: points[0].y }, { x: points[0].x, y: points[0].y },
{ x: points[0].x + (points[1].y - points[0].y), y: points[0].y + (points[0].x - points[1].x) }, { x: points[0].x + (points[1].y - points[0].y), y: points[0].y + (points[0].x - points[1].x) },
{ x: points[0].x + (points[1].y - points[0].y) + (points[2].y - points[1].y), y: points[0].y + (points[0].x - points[1].x) }, {
x: points[0].x + (points[1].y - points[0].y) + (points[2].y - points[1].y),
y: points[0].y + (points[0].x - points[1].x),
},
{ x: points[0].x + (points[1].y - points[0].y) + (points[2].y - points[1].y), y: points[0].y }, { x: points[0].x + (points[1].y - points[0].y) + (points[2].y - points[1].y), y: points[0].y },
] ]
rightPoints = [ rightPoints = [
{ x: points[0].x, y: points[0].y }, { x: points[0].x, y: points[0].y },
{ x: points[0].x + (points[1].y - points[0].y), y: points[0].y - (points[0].x - points[1].x) }, { x: points[0].x + (points[1].y - points[0].y), y: points[0].y - (points[0].x - points[1].x) },
{ x: points[0].x + (points[1].y - points[0].y) + (points[2].y - points[1].y), y: points[0].y - (points[0].x - points[1].x) }, {
x: points[0].x + (points[1].y - points[0].y) + (points[2].y - points[1].y),
y: points[0].y - (points[0].x - points[1].x),
},
{ x: points[0].x + (points[1].y - points[0].y) + (points[2].y - points[1].y), y: points[0].y }, { x: points[0].x + (points[1].y - points[0].y) + (points[2].y - points[1].y), y: points[0].y },
] ]
} }

View File

@ -10,7 +10,7 @@ import GridMove from '@/components/floor-plan/modal/grid/GridMove'
import GridCopy from '@/components/floor-plan/modal/grid/GridCopy' import GridCopy from '@/components/floor-plan/modal/grid/GridCopy'
import ColorPickerModal from '@/components/common/color-picker/ColorPickerModal' import ColorPickerModal from '@/components/common/color-picker/ColorPickerModal'
import { gridColorState } from '@/store/gridAtom' import { gridColorState } from '@/store/gridAtom'
import { contextPopupPositionState } from '@/store/popupAtom' import { contextPopupPositionState, contextPopupState } from '@/store/popupAtom'
import AuxiliaryCopy from '@/components/floor-plan/modal/auxiliary/AuxiliaryCopy' import AuxiliaryCopy from '@/components/floor-plan/modal/auxiliary/AuxiliaryCopy'
import SizeSetting from '@/components/floor-plan/modal/object/SizeSetting' import SizeSetting from '@/components/floor-plan/modal/object/SizeSetting'
import RoofMaterialSetting from '@/components/floor-plan/modal/object/RoofMaterialSetting' import RoofMaterialSetting from '@/components/floor-plan/modal/object/RoofMaterialSetting'
@ -37,7 +37,7 @@ export function useContextMenu() {
const currentMenu = useRecoilValue(currentMenuState) // 현재 메뉴 const currentMenu = useRecoilValue(currentMenuState) // 현재 메뉴
const setContextPopupPosition = useSetRecoilState(contextPopupPositionState) // 현재 메뉴 const setContextPopupPosition = useSetRecoilState(contextPopupPositionState) // 현재 메뉴
const [contextMenu, setContextMenu] = useState([[]]) // 메뉴.object 별 context menu const [contextMenu, setContextMenu] = useState([[]]) // 메뉴.object 별 context menu
const [currentContextMenu, setCurrentContextMenu] = useState(null) // 선택한 contextMenu const [currentContextMenu, setCurrentContextMenu] = useRecoilState(contextPopupState) // 선택한 contextMenu
const currentObject = useRecoilValue(currentObjectState) const currentObject = useRecoilValue(currentObjectState)
const { getMessage } = useMessage() const { getMessage } = useMessage()
const { addPopup } = usePopup() const { addPopup } = usePopup()

View File

@ -1,14 +1,15 @@
import { useRecoilState } from 'recoil' import { useRecoilState } from 'recoil'
import { popupState } from '@/store/popupAtom' import { contextPopupState, popupState } from '@/store/popupAtom'
export function usePopup() { export function usePopup() {
const [popup, setPopup] = useRecoilState(popupState) const [popup, setPopup] = useRecoilState(popupState)
const [contextMenuPopup, setContextMenuPopup] = useRecoilState(contextPopupState)
const addPopup = (id, depth, component) => { const addPopup = (id, depth, component) => {
setPopup({ children: [...filterDepth(depth), { id: id, depth: depth, component: component }] }) setPopup({ children: [...filterDepth(depth), { id: id, depth: depth, component: component }] })
} }
const closePopup = (id) => { const closePopup = (id) => {
if (contextMenuPopup) setContextMenuPopup(null)
setPopup({ children: [...filterChildrenPopup(id).filter((child) => child.id !== id)] }) setPopup({ children: [...filterChildrenPopup(id).filter((child) => child.id !== id)] })
} }

View File

@ -293,10 +293,12 @@
"contextmenu.select.move": "선택・이동(JA)", "contextmenu.select.move": "선택・이동(JA)",
"contextmenu.wallline.remove": "외벽선 삭제(JA)", "contextmenu.wallline.remove": "외벽선 삭제(JA)",
"contextmenu.size.edit": "サイズ変更", "contextmenu.size.edit": "サイズ変更",
"modal.auxiliary.size.edit": "補助線サイズ変更",
"modal.auxiliary.size.edit.point": "支店",
"contextmenu.auxiliary.move": "補助線の移動", "contextmenu.auxiliary.move": "補助線の移動",
"modal.auxiliary.move": "補助線の移動", "modal.auxiliary.move": "補助線の移動",
"modal.auxiliary.move.info": "移動する方向を入力してください", "modal.auxiliary.move.info": "移動する方向を入力してください",
"contextmenu.auxiliary.copy": "コピーする方向を入力してください", "contextmenu.auxiliary.copy": "補助線のコピー",
"modal.auxiliary.copy": "補助線のコピー", "modal.auxiliary.copy": "補助線のコピー",
"modal.auxiliary.copy.info": "コピーする方向を入力してください", "modal.auxiliary.copy.info": "コピーする方向を入力してください",
"contextmenu.auxiliary.remove": "보조선 삭제(JA)", "contextmenu.auxiliary.remove": "보조선 삭제(JA)",

View File

@ -298,10 +298,14 @@
"contextmenu.select.move": "선택・이동", "contextmenu.select.move": "선택・이동",
"contextmenu.wallline.remove": "외벽선 삭제", "contextmenu.wallline.remove": "외벽선 삭제",
"contextmenu.size.edit": "사이즈 변경", "contextmenu.size.edit": "사이즈 변경",
"modal.auxiliary.size.edit": "보조선 사이즈 변경",
"modal.auxiliary.size.edit.point": "지점",
"contextmenu.auxiliary.move": "보조선 이동", "contextmenu.auxiliary.move": "보조선 이동",
"modal.auxiliary.move": "보조선 이동", "modal.auxiliary.move": "보조선 이동",
"modal.auxiliary.move.info": "이동할 방향을 입력해주세요.", "modal.auxiliary.move.info": "이동할 방향을 입력해주세요.",
"contextmenu.auxiliary.copy": "보조선 복사", "contextmenu.auxiliary.copy": "보조선 복사",
"modal.auxiliary.copy": "보조선 복사",
"modal.auxiliary.copy.info": "복사할 방향을 입력해주세요.",
"contextmenu.auxiliary.remove": "보조선 삭제", "contextmenu.auxiliary.remove": "보조선 삭제",
"contextmenu.auxiliary.vertical.bisector": "보조선 수직이등분선", "contextmenu.auxiliary.vertical.bisector": "보조선 수직이등분선",
"contextmenu.auxiliary.cut": "보조선 절삭", "contextmenu.auxiliary.cut": "보조선 절삭",

View File

@ -12,6 +12,12 @@ export const popupState = atom({
dangerouslyAllowMutability: true, dangerouslyAllowMutability: true,
}) })
export const contextPopupState = atom({
key: 'contextPopupState',
default: null,
dangerouslyAllowMutability: true,
})
export const contextPopupPositionState = atom({ export const contextPopupPositionState = atom({
key: 'contextPopupPositionState', key: 'contextPopupPositionState',
default: { default: {