Merge branch 'qcast-pub' into dev

This commit is contained in:
minsik 2024-11-04 16:12:38 +09:00
commit 291109719a
13 changed files with 120 additions and 46 deletions

View File

@ -3,12 +3,14 @@ import { useEffect } from 'react'
import '@/styles/contents.scss' import '@/styles/contents.scss'
import { useRecoilState } from 'recoil' import { useRecoilState } from 'recoil'
import { contextMenuListState, contextMenuState } from '@/store/contextMenu' import { contextMenuListState, contextMenuState } from '@/store/contextMenu'
import { useTempGrid } from '@/hooks/useTempGrid'
export default function QContextMenu(props) { export default function QContextMenu(props) {
const { contextRef, canvasProps, handleKeyup } = props const { contextRef, canvasProps, handleKeyup } = props
const [contextMenu, setContextMenu] = useRecoilState(contextMenuState) const [contextMenu, setContextMenu] = useRecoilState(contextMenuState)
const [contextMenuList, setContextMenuList] = useRecoilState(contextMenuListState) const [contextMenuList, setContextMenuList] = useRecoilState(contextMenuListState)
const activeObject = canvasProps?.getActiveObject() // const activeObject = canvasProps?.getActiveObject() //
const { tempGridMode, setTempGridMode } = useTempGrid()
let contextType = '' let contextType = ''
@ -32,6 +34,7 @@ export default function QContextMenu(props) {
const handleContextMenu = (e) => { const handleContextMenu = (e) => {
// e.preventDefault() // contextmenu // e.preventDefault() // contextmenu
if (tempGridMode) return
const position = { const position = {
x: window.innerWidth / 2 < e.pageX ? e.pageX - 240 : e.pageX, x: window.innerWidth / 2 < e.pageX ? e.pageX - 240 : e.pageX,
y: window.innerHeight / 2 < e.pageY ? getYPosition(e) : e.pageY, y: window.innerHeight / 2 < e.pageY ? getYPosition(e) : e.pageY,

View File

@ -47,7 +47,7 @@ const fontColors = [
] ]
export default function FontSetting(props) { export default function FontSetting(props) {
const contextPopupPosition = useRecoilValue(contextPopupPositionState) const contextPopupPosition = useRecoilValue(contextPopupPositionState)
const { id, setIsShow, pos = contextPopupPosition, type } = props const { id, setIsShow, pos = contextPopupPosition, type, isConfig = false } = props
const { getMessage } = useMessage() const { getMessage } = useMessage()
const { closePopup } = usePopup() const { closePopup } = usePopup()
const [globalFont, setGlobalFont] = useRecoilState(globalFontAtom) const [globalFont, setGlobalFont] = useRecoilState(globalFontAtom)
@ -83,7 +83,7 @@ export default function FontSetting(props) {
className="modal-close" className="modal-close"
onClick={() => { onClick={() => {
if (setIsShow) setIsShow(false) if (setIsShow) setIsShow(false)
closePopup(id) closePopup(id, isConfig)
}} }}
> >
닫기 닫기

View File

@ -5,5 +5,9 @@ import { Fragment } from 'react'
export default function PopupManager() { export default function PopupManager() {
const [popup, setPopup] = useRecoilState(popupState) const [popup, setPopup] = useRecoilState(popupState)
return popup.children?.map((child) => <Fragment key={child.id}>{child.component}</Fragment>)
return [
...popup?.config.map((child) => <Fragment key={child.id}>{child.component}</Fragment>),
...popup?.other.map((child) => <Fragment key={child.id}>{child.component}</Fragment>),
]
} }

View File

@ -51,7 +51,7 @@ export default function CanvasMenu(props) {
const sessionState = useRecoilValue(sessionStore) const sessionState = useRecoilValue(sessionStore)
const globalLocale = useRecoilValue(globalLocaleStore) const globalLocale = useRecoilValue(globalLocaleStore)
const canvas = useRecoilValue(canvasState) const canvas = useRecoilValue(canvasState)
const { handleZoomClear } = useCanvasEvent() const { handleZoomClear, handleZoom } = useCanvasEvent()
const { handleMenu } = useMenu() const { handleMenu } = useMenu()
const { handleEstimateSubmit } = useEstimateController() const { handleEstimateSubmit } = useEstimateController()
@ -132,7 +132,7 @@ export default function CanvasMenu(props) {
const handlePopup = () => { const handlePopup = () => {
const id = uuidv4() const id = uuidv4()
addPopup(id, 0, <SettingModal01 id={id} />) addPopup(id, 1, <SettingModal01 id={id} />, true)
} }
useEffect(() => { useEffect(() => {
@ -204,14 +204,18 @@ export default function CanvasMenu(props) {
<button <button
className="control-btn minus" className="control-btn minus"
onClick={() => { onClick={() => {
canvas.setZoom(canvas.getZoom() - 0.1) handleZoom(false)
}} }}
></button> ></button>
<span>{canvasZoom}%</span> <span>{canvasZoom}%</span>
<button className="control-btn plus" onClick={handleZoomClear}></button> <button
className="control-btn plus"
onClick={() => {
handleZoom(true)
}}
></button>
</div> </div>
<div className="btn-from"> <div className="btn-from">
<button className="btn07" onClick={handleClear}></button>
<button className="btn08" onClick={handleSaveCanvas}></button> <button className="btn08" onClick={handleSaveCanvas}></button>
<button className="btn09"></button> <button className="btn09"></button>
</div> </div>

View File

@ -78,14 +78,14 @@ export default function GridOption() {
// //
setShowDotLineGridModal(selectedOption.selected) setShowDotLineGridModal(selectedOption.selected)
addPopup(dotLineId, 2, <DotLineGrid {...dotLineGridProps} />) addPopup(dotLineId, 2, <DotLineGrid {...dotLineGridProps} />, true)
} else if (selectedOption.id === 3) { } else if (selectedOption.id === 3) {
// //
setAdsorptionPointAddMode(selectedOption.selected) setAdsorptionPointAddMode(selectedOption.selected)
} else if (selectedOption.id === 4) { } else if (selectedOption.id === 4) {
// //
setShowColorPickerModal(selectedOption.selected) setShowColorPickerModal(selectedOption.selected)
addPopup(colorId, 2, <ColorPickerModal {...colorPickerProps} />) addPopup(colorId, 2, <ColorPickerModal {...colorPickerProps} />, true)
} }
setGridOptions(newGridOptions) setGridOptions(newGridOptions)

View File

@ -1,4 +1,4 @@
import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil' import { useRecoilValue } from 'recoil'
import { useMessage } from '@/hooks/useMessage' import { useMessage } from '@/hooks/useMessage'
import React, { useEffect, useState } from 'react' import React, { useEffect, useState } from 'react'
import DimensionLineSetting from '@/components/floor-plan/modal/setting01/dimensionLine/DimensionLineSetting' import DimensionLineSetting from '@/components/floor-plan/modal/setting01/dimensionLine/DimensionLineSetting'
@ -67,6 +67,7 @@ export default function SecondOption() {
id: fontId, id: fontId,
pos: { x: 745, y: 180 }, pos: { x: 745, y: 180 },
setIsShow: setShowFontSettingModal, setIsShow: setShowFontSettingModal,
isConfig: true,
} }
const planSizeProps = { const planSizeProps = {
id: planSizeId, id: planSizeId,
@ -86,36 +87,41 @@ export default function SecondOption() {
case 'font1': { case 'font1': {
// //
setShowFontSettingModal(true) setShowFontSettingModal(true)
setShowDimensionLineSettingModal(false)
fontProps.type = 'commonText' fontProps.type = 'commonText'
fontProps.id = fontId + 1 fontProps.id = fontId + 1
addPopup(fontId + 1, 2, <FontSetting {...fontProps} />) addPopup(fontId + 1, 2, <FontSetting {...fontProps} />, true)
break break
} }
case 'font2': { case 'font2': {
// //
setShowFontSettingModal(true) setShowFontSettingModal(true)
setShowDimensionLineSettingModal(false)
fontProps.type = 'flowText' fontProps.type = 'flowText'
fontProps.id = fontId + 2 fontProps.id = fontId + 2
addPopup(fontId + 2, 2, <FontSetting {...fontProps} />) addPopup(fontId + 2, 2, <FontSetting {...fontProps} />, true)
break break
} }
case 'font3': { case 'font3': {
// //
setShowFontSettingModal(true) setShowFontSettingModal(true)
setShowDimensionLineSettingModal(false)
fontProps.type = 'lengthText' fontProps.type = 'lengthText'
fontProps.id = fontId + 3 fontProps.id = fontId + 3
addPopup(fontId + 3, 2, <FontSetting {...fontProps} />) addPopup(fontId + 3, 2, <FontSetting {...fontProps} />, true)
break break
} }
case 'font4': { case 'font4': {
// //
setShowFontSettingModal(true) setShowFontSettingModal(true)
setShowDimensionLineSettingModal(false)
fontProps.type = 'circuitNumberText' fontProps.type = 'circuitNumberText'
fontProps.id = fontId fontProps.id = fontId
addPopup(fontId, 2, <FontSetting {...fontProps} />) addPopup(fontId, 2, <FontSetting {...fontProps} />, true)
break break
} }
@ -123,7 +129,7 @@ export default function SecondOption() {
// //
if (!showDimensionLineSettingModal) { if (!showDimensionLineSettingModal) {
setShowDimensionLineSettingModal(true) setShowDimensionLineSettingModal(true)
addPopup(dimensionId, 2, <DimensionLineSetting {...dimensionProps} />) addPopup(dimensionId, 2, <DimensionLineSetting {...dimensionProps} />, true)
} else { } else {
setShowDimensionLineSettingModal(false) setShowDimensionLineSettingModal(false)
closePopup(dimensionId) closePopup(dimensionId)
@ -134,7 +140,8 @@ export default function SecondOption() {
case 'planSize': { case 'planSize': {
// //
setShowPlanSizeSettingModal(true) setShowPlanSizeSettingModal(true)
addPopup(planSizeId, 2, <PlanSizeSetting {...planSizeProps} />) setShowDimensionLineSettingModal(false)
addPopup(planSizeId, 2, <PlanSizeSetting {...planSizeProps} />, true)
break break
} }
} }

View File

@ -11,7 +11,7 @@ import { useRecoilValue } from 'recoil'
import { usePopup } from '@/hooks/usePopup' import { usePopup } from '@/hooks/usePopup'
export default function SettingModal01(props) { export default function SettingModal01(props) {
const { setShowDotLineGridModal, setShowFontSettingModal, id } = props const { setShowDotLineGridModal, setShowFontSettingModal, id, isConfig } = props
console.log(props) console.log(props)
const [buttonAct, setButtonAct] = useState(1) const [buttonAct, setButtonAct] = useState(1)
const { getMessage } = useMessage() const { getMessage } = useMessage()
@ -27,7 +27,7 @@ export default function SettingModal01(props) {
<div className={`modal-pop-wrap sm mount`}> <div className={`modal-pop-wrap sm mount`}>
<div className="modal-head"> <div className="modal-head">
<h1 className="title">{getMessage('modal.canvas.setting')}</h1> <h1 className="title">{getMessage('modal.canvas.setting')}</h1>
<button className="modal-close" onClick={() => closePopup(id)}> <button className="modal-close" onClick={() => closePopup(id, true)}>
닫기 닫기
</button> </button>
</div> </div>

View File

@ -87,6 +87,7 @@ export default function DimensionLineSetting(props) {
setFontColor: setOriginFontColor, setFontColor: setOriginFontColor,
fontSize: originFontSize, fontSize: originFontSize,
setFontSize: setOriginFontSize, setFontSize: setOriginFontSize,
isConfig: true,
id: fontModalId, id: fontModalId,
pos: { pos: {
x: 455, x: 455,
@ -97,17 +98,17 @@ export default function DimensionLineSetting(props) {
const popupHandle = (type) => { const popupHandle = (type) => {
switch (type) { switch (type) {
case 'color': case 'color':
addPopup(colorModalId, 3, <ColorPickerModal {...colorPickerProps} />) addPopup(colorModalId, 3, <ColorPickerModal {...colorPickerProps} />, true)
break break
case 'font': case 'font':
addPopup(fontModalId, 3, <FontSetting {...fontProps} />) addPopup(fontModalId, 3, <FontSetting {...fontProps} />, true)
break break
} }
} }
return ( return (
<WithDraggable isShow={true} pos={pos}> <WithDraggable isShow={true} pos={pos}>
<div className={`modal-pop-wrap xxxm`}> <div className={`modal-pop-wrap xxxm mount`}>
<div className="modal-head"> <div className="modal-head">
<h1 className="title">{getMessage('modal.canvas.setting.font.plan.absorption.dimension.line')} </h1> <h1 className="title">{getMessage('modal.canvas.setting.font.plan.absorption.dimension.line')} </h1>
<button <button

View File

@ -15,14 +15,14 @@ export default function PlanSizeSetting(props) {
return ( return (
<WithDraggable isShow={true} pos={pos}> <WithDraggable isShow={true} pos={pos}>
<div className={`modal-pop-wrap xsm`}> <div className={`modal-pop-wrap xsm mount`}>
<div className="modal-head"> <div className="modal-head">
<h1 className="title">{getMessage('modal.canvas.setting.font.plan.absorption.plan.size.setting')}</h1> <h1 className="title">{getMessage('modal.canvas.setting.font.plan.absorption.plan.size.setting')}</h1>
<button <button
className="modal-close" className="modal-close"
onClick={() => { onClick={() => {
setIsShow(false) setIsShow(false)
closePopup(id) closePopup(id, true)
}} }}
> >
닫기 닫기

View File

@ -1,4 +1,4 @@
import { useState } from 'react' import { useEffect, useState } from 'react'
import { useRecoilState, useRecoilValue } from 'recoil' import { useRecoilState, useRecoilValue } from 'recoil'
import { v4 as uuidv4 } from 'uuid' import { v4 as uuidv4 } from 'uuid'
import { canvasSizeState, canvasState, canvasZoomState, currentObjectState, fontFamilyState, fontSizeState } from '@/store/canvasAtom' import { canvasSizeState, canvasState, canvasZoomState, currentObjectState, fontFamilyState, fontSizeState } from '@/store/canvasAtom'
@ -18,6 +18,10 @@ export function useCanvasEvent() {
const lengthTextOption = useRecoilValue(fontSelector('lengthText')) const lengthTextOption = useRecoilValue(fontSelector('lengthText'))
const { modifiedPlanFlag, setModifiedPlanFlag } = usePlan() const { modifiedPlanFlag, setModifiedPlanFlag } = usePlan()
useEffect(() => {
canvas?.setZoom(canvasZoom / 100)
}, [canvasZoom])
// 기본적인 이벤트 필요시 추가 // 기본적인 이벤트 필요시 추가
const attachDefaultEventOnCanvas = () => { const attachDefaultEventOnCanvas = () => {
removeEventOnCanvas() removeEventOnCanvas()
@ -365,6 +369,14 @@ export function useCanvasEvent() {
}) })
} }
const handleZoom = (isZoom) => {
if (isZoom) {
setCanvasZoom(canvasZoom + 10)
} else {
setCanvasZoom(canvasZoom - 10)
}
}
const handleZoomClear = () => { const handleZoomClear = () => {
setCanvasZoom(100) setCanvasZoom(100)
canvas.set({ zoom: 1 }) canvas.set({ zoom: 1 })
@ -376,5 +388,6 @@ export function useCanvasEvent() {
setCanvasForEvent, setCanvasForEvent,
attachDefaultEventOnCanvas, attachDefaultEventOnCanvas,
handleZoomClear, handleZoomClear,
handleZoom,
} }
} }

View File

@ -244,7 +244,7 @@ export function useContextMenu() {
if (temp.length > 0) menu = temp if (temp.length > 0) menu = temp
} }
handleClick(null, menu) if (menu) handleClick(null, menu)
} }
useEffect(() => { useEffect(() => {
@ -256,8 +256,6 @@ export function useContextMenu() {
}, [currentContextMenu]) }, [currentContextMenu])
useEffect(() => { useEffect(() => {
console.log('currentObject', currentObject)
if (currentObject?.name) { if (currentObject?.name) {
console.log(currentObject?.name) console.log(currentObject?.name)
switch (currentObject.name) { switch (currentObject.name) {
@ -477,7 +475,7 @@ export function useContextMenu() {
{ {
id: 'dimensionLineDisplayEdit', id: 'dimensionLineDisplayEdit',
name: getMessage('contextmenu.display.edit'), name: getMessage('contextmenu.display.edit'),
component: <DimensionLineSetting id={popupId} />, component: <DimensionLineSetting id={popupId} isConfig={false} />,
}, },
], ],
]) ])

View File

@ -4,47 +4,90 @@ 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 [contextMenuPopup, setContextMenuPopup] = useRecoilState(contextPopupState)
const addPopup = (id, depth, component) => {
setPopup({ children: [...filterDepth(depth), { id: id, depth: depth, component: component }] }) const addPopup = (id, depth, component, isConfig = false) => {
setPopup({
config: isConfig ? [...filterDepth(depth, isConfig), { id, depth, component, isConfig }] : [...popup.config],
other: !isConfig ? [...filterDepth(depth, isConfig), { id, depth, component, isConfig }] : [...popup.other],
})
} }
const closePopup = (id) => { const closePopup = (id, isConfig = false) => {
if (contextMenuPopup) setContextMenuPopup(null) if (contextMenuPopup) setContextMenuPopup(null)
setPopup({ children: [...filterChildrenPopup(id).filter((child) => child.id !== id)] }) if (isConfig) {
setPopup({
config: [...filterChildrenPopup(id, isConfig).filter((child) => child.id !== id)],
other: popup.other,
})
} else {
setPopup({
config: popup.config,
other: [...filterChildrenPopup(id, isConfig).filter((child) => child.id !== id)],
})
}
} }
const filterPopup = (depth) => { const filterPopup = (depth) => {
setPopup({ children: [...filterDepth(depth)] }) setPopup({
config: [...filterDepth(depth)],
other: [],
})
} }
const filterChildrenPopup = (id) => { const filterChildrenPopup = (id, isConfig) => {
const target = popup.children.filter((child) => child.id === id) let target = []
if (target.length !== 0) { if (isConfig) {
return popup.children.filter((child) => child.depth <= target[0].depth) target = popup?.config.filter((child) => child.id === id)
} else {
target = popup?.other.filter((child) => child.id === id)
} }
return popup.children if (target.length !== 0) {
if (isConfig) {
return popup?.config.filter((child) => child.depth <= target[0].depth)
} else {
return popup?.other.filter((child) => child.depth <= target[0].depth)
}
} else {
if (isConfig) {
return popup.config
} else {
return popup.other
}
}
} }
const closePopups = (ids) => { const closePopups = (ids) => {
setPopup({ children: [...popup.children.filter((child) => !ids.includes(child.id))] }) setPopup({
config: [...popup?.config.filter((child) => !ids.includes(child.id))],
other: [...popup?.other.filter((child) => !ids.includes(child.id))],
})
} }
const closeAll = () => { const closeAll = () => {
setPopup({ children: [] }) setPopup({
other: [],
config: [],
})
} }
const closePrevPopup = () => { const closePrevPopup = () => {
setPopup({ children: [...popup.children.slice(popup.children.length - 1)] }) setPopup({
config: [...popup?.slice(popup?.length - 1)],
other: [],
})
} }
const filterDepth = (depth) => { const filterDepth = (depth, isConfig) => {
return [...popup.children.filter((child) => child.depth !== depth)] if (isConfig) {
return [...popup?.config.filter((child) => child.depth < depth)]
} else {
return [...popup?.other.filter((child) => child.depth < depth)]
}
} }
return { return {
popup, popup,
setPopup,
addPopup, addPopup,
closePopup, closePopup,
closePopups, closePopups,

View File

@ -7,7 +7,8 @@ import { atom } from 'recoil'
export const popupState = atom({ export const popupState = atom({
key: 'popupState', key: 'popupState',
default: { default: {
children: [], config: [],
other: [],
}, },
dangerouslyAllowMutability: true, dangerouslyAllowMutability: true,
}) })