669 lines
19 KiB
JavaScript
669 lines
19 KiB
JavaScript
import { useEffect, useRef, useState } from 'react'
|
|
import { useMessage } from '@/hooks/useMessage'
|
|
import { useRecoilValue, useSetRecoilState } from 'recoil'
|
|
import { ANGLE_TYPE, canvasState, currentAngleTypeSelector, currentMenuState, currentObjectState, pitchTextSelector } from '@/store/canvasAtom'
|
|
import { LINE_TYPE, POLYGON_TYPE } from '@/common/common'
|
|
import { usePolygon } from '@/hooks/usePolygon'
|
|
import { useMode } from '@/hooks/useMode'
|
|
import { useLine } from '@/hooks/useLine'
|
|
import { outerLineFixState } from '@/store/outerLineAtom'
|
|
import { useSwal } from '@/hooks/useSwal'
|
|
import { usePopup } from '@/hooks/usePopup'
|
|
import { getChonByDegree } from '@/util/canvas-util'
|
|
|
|
// 지붕형상 설정
|
|
export function useRoofShapeSetting(id) {
|
|
const [shapeNum, setShapeNum] = useState(1)
|
|
const [buttonAct, setButtonAct] = useState(1)
|
|
const { swalFire } = useSwal()
|
|
const { getMessage } = useMessage()
|
|
const canvas = useRecoilValue(canvasState)
|
|
const currentAngleType = useRecoilValue(currentAngleTypeSelector)
|
|
const pitchText = useRecoilValue(pitchTextSelector)
|
|
const { addPolygonByLines } = usePolygon()
|
|
|
|
const [pitch, setPitch] = useState(currentAngleType === ANGLE_TYPE.SLOPE ? 4 : 21.8) // 경사
|
|
const [eavesOffset, setEavesOffset] = useState(500) // 처마출폭
|
|
const [gableOffset, setGableOffset] = useState(300) // 케라바출폭
|
|
const [sleeveOffset, setSleeveOffset] = useState(300) // 소매출폭
|
|
const [jerkinHeadWidth, setJerkinHeadWidth] = useState(800) // 반절처 폭
|
|
const [jerkinHeadPitch, setJerkinHeadPitch] = useState(currentAngleType === ANGLE_TYPE.SLOPE ? 4.5 : 20) // 반절처 경사
|
|
const [hipAndGableWidth, setHipAndGableWidth] = useState(800) // 팔작지붕 폭
|
|
const [shedPitch, setShedPitch] = useState(currentAngleType === ANGLE_TYPE.SLOPE ? 4 : 21.8) // 팔작지붕 폭
|
|
const [shedWidth, setShedWidth] = useState(300) // 한쪽흐름 폭
|
|
const [hasSleeve, setHasSleeve] = useState('0')
|
|
const currentObject = useRecoilValue(currentObjectState)
|
|
const { drawRoofPolygon } = useMode()
|
|
const { hideLine, showLine, removePitchText, addPitchText, addPitchTextsByOuterLines } = useLine()
|
|
|
|
const setCurrentMenu = useSetRecoilState(currentMenuState)
|
|
const outerLineFix = useRecoilValue(outerLineFixState)
|
|
|
|
const isFixRef = useRef(false)
|
|
|
|
const pitchRef = useRef(null)
|
|
const shedPitchRef = useRef(null)
|
|
const jerkinHeadPitchRef = useRef(null)
|
|
|
|
const history = useRef([])
|
|
const { closePopup } = usePopup()
|
|
|
|
useEffect(() => {
|
|
pitchRef.current = currentAngleType === ANGLE_TYPE.SLOPE ? pitch : getChonByDegree(pitch)
|
|
}, [pitch])
|
|
useEffect(() => {
|
|
shedPitchRef.current = currentAngleType === ANGLE_TYPE.SLOPE ? shedPitch : getChonByDegree(shedPitch)
|
|
}, [shedPitch])
|
|
useEffect(() => {
|
|
jerkinHeadPitchRef.current = currentAngleType === ANGLE_TYPE.SLOPE ? jerkinHeadPitch : getChonByDegree(jerkinHeadPitch)
|
|
}, [jerkinHeadPitch])
|
|
|
|
useEffect(() => {
|
|
const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
|
if (!outerLineFix || outerLines.length === 0) {
|
|
swalFire({ text: '외벽선이 없습니다.' })
|
|
// setShowRoofShapeSettingModal(false)
|
|
closePopup(id)
|
|
}
|
|
|
|
return () => {
|
|
if (!isFixRef.current) {
|
|
return
|
|
}
|
|
|
|
const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
|
const pitchTexts = canvas.getObjects().filter((obj) => obj.name === 'pitchText')
|
|
canvas.remove(...pitchTexts)
|
|
outerLines.forEach((line) => {
|
|
let stroke, strokeWidth
|
|
if (line.attributes) {
|
|
if (line.attributes.type === LINE_TYPE.WALLLINE.EAVES || line.attributes.type === LINE_TYPE.WALLLINE.HIPANDGABLE) {
|
|
stroke = '#45CD7D'
|
|
strokeWidth = 4
|
|
} else if (line.attributes.type === LINE_TYPE.WALLLINE.GABLE || line.attributes.type === LINE_TYPE.WALLLINE.JERKINHEAD) {
|
|
stroke = '#3FBAE6'
|
|
strokeWidth = 4
|
|
} else {
|
|
stroke = '#000000'
|
|
strokeWidth = 4
|
|
}
|
|
|
|
line.set({
|
|
stroke,
|
|
strokeWidth,
|
|
})
|
|
|
|
addPitchText(line)
|
|
}
|
|
})
|
|
canvas.renderAll()
|
|
}
|
|
}, [])
|
|
|
|
useEffect(() => {
|
|
if (shapeNum !== 4) {
|
|
return
|
|
}
|
|
if (!currentObject) {
|
|
return
|
|
}
|
|
if (currentObject.name !== 'outerLine') {
|
|
return
|
|
}
|
|
|
|
/*const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
|
outerLines.forEach((line) => {
|
|
line.set({
|
|
stroke: '#000000',
|
|
strokeWidth: 4,
|
|
})
|
|
})*/
|
|
|
|
currentObject.set({
|
|
stroke: '#EA10AC',
|
|
strokeWidth: 4,
|
|
})
|
|
|
|
canvas.renderAll()
|
|
}, [currentObject])
|
|
|
|
useEffect(() => {
|
|
if (shapeNum === 4) {
|
|
canvas?.remove(canvas.getObjects().find((obj) => obj.name === POLYGON_TYPE.WALL))
|
|
const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
|
outerLines.forEach((line) => {
|
|
showLine(line)
|
|
line.bringToFront()
|
|
})
|
|
|
|
canvas?.renderAll()
|
|
}
|
|
setEavesOffset(500)
|
|
setGableOffset(300)
|
|
setSleeveOffset(300)
|
|
setJerkinHeadWidth(800)
|
|
setHipAndGableWidth(800)
|
|
setShedWidth(300)
|
|
}, [shapeNum])
|
|
|
|
const shapeMenu = [
|
|
{ id: 1, name: getMessage('modal.roof.shape.setting.ridge') }, // 용마루
|
|
{ id: 2, name: getMessage('modal.roof.shape.setting.patten.a') }, // 패턴A
|
|
{ id: 3, name: getMessage('modal.roof.shape.setting.patten.b') }, // 패턴B
|
|
{ id: 4, name: getMessage('modal.roof.shape.setting.side') }, // 변별로 설정
|
|
{ id: 5, name: getMessage('commons.west') }, // 서
|
|
{ id: 6, name: getMessage('commons.east') }, // 동
|
|
{ id: 7, name: getMessage('commons.south') }, // 남
|
|
{ id: 8, name: getMessage('commons.north') }, // 북
|
|
]
|
|
|
|
const buttonMenu = [
|
|
{ id: 1, name: getMessage('eaves') },
|
|
{ id: 2, name: getMessage('gable') },
|
|
{ id: 3, name: getMessage('wall') },
|
|
{ id: 4, name: getMessage('hipandgable') },
|
|
{ id: 5, name: getMessage('jerkinhead') },
|
|
{ id: 6, name: getMessage('shed') },
|
|
]
|
|
|
|
const handleSave = () => {
|
|
//기존 wallLine 삭제
|
|
|
|
let outerLines
|
|
let direction
|
|
|
|
switch (shapeNum) {
|
|
case 1: {
|
|
outerLines = saveRidge()
|
|
break
|
|
}
|
|
case 2: {
|
|
outerLines = saveAPattern()
|
|
break
|
|
}
|
|
case 3: {
|
|
outerLines = saveBPattern()
|
|
break
|
|
}
|
|
case 4: {
|
|
outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
|
outerLines.forEach((line) => {
|
|
// hideLine(line)
|
|
})
|
|
break
|
|
}
|
|
|
|
case 5: {
|
|
// 서쪽
|
|
initLineSetting()
|
|
outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
|
direction = 'west'
|
|
|
|
outerLines.forEach((line) => {
|
|
setWestAndEastRoof(line)
|
|
if (outerLines[0].direction === 'bottom') {
|
|
if (line.direction === 'bottom') {
|
|
line.attributes = {
|
|
offset: eavesOffset / 10,
|
|
pitch: pitchRef.current,
|
|
type: LINE_TYPE.WALLLINE.EAVES,
|
|
}
|
|
}
|
|
|
|
if (line.direction === 'top') {
|
|
line.attributes = {
|
|
offset: shedWidth / 10,
|
|
pitch: pitch,
|
|
type: LINE_TYPE.WALLLINE.SHED,
|
|
}
|
|
}
|
|
} else {
|
|
if (line.direction === 'top') {
|
|
line.attributes = {
|
|
offset: eavesOffset / 10,
|
|
pitch: pitchRef.current,
|
|
type: LINE_TYPE.WALLLINE.EAVES,
|
|
}
|
|
}
|
|
|
|
if (line.direction === 'bottom') {
|
|
line.attributes = {
|
|
offset: shedWidth / 10,
|
|
pitch: pitchRef.current,
|
|
type: LINE_TYPE.WALLLINE.SHED,
|
|
}
|
|
}
|
|
}
|
|
|
|
// hideLine(line)
|
|
})
|
|
break
|
|
}
|
|
case 6: {
|
|
initLineSetting()
|
|
outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
|
direction = 'east'
|
|
|
|
outerLines.forEach((line) => {
|
|
setWestAndEastRoof(line)
|
|
|
|
if (outerLines[0].direction === 'bottom') {
|
|
if (line.direction === 'top') {
|
|
line.attributes = {
|
|
offset: eavesOffset / 10,
|
|
pitch: pitchRef.current,
|
|
type: LINE_TYPE.WALLLINE.EAVES,
|
|
}
|
|
}
|
|
|
|
if (line.direction === 'bottom') {
|
|
line.attributes = {
|
|
offset: shedWidth / 10,
|
|
pitch: pitchRef.current,
|
|
type: LINE_TYPE.WALLLINE.SHED,
|
|
}
|
|
}
|
|
} else {
|
|
if (line.direction === 'bottom') {
|
|
line.attributes = {
|
|
offset: eavesOffset / 10,
|
|
pitch: pitchRef.current,
|
|
type: LINE_TYPE.WALLLINE.EAVES,
|
|
}
|
|
}
|
|
|
|
if (line.direction === 'top') {
|
|
line.attributes = {
|
|
offset: shedWidth / 10,
|
|
pitch: pitchRef.current,
|
|
type: LINE_TYPE.WALLLINE.SHED,
|
|
}
|
|
}
|
|
}
|
|
|
|
// hideLine(line)
|
|
})
|
|
break
|
|
}
|
|
case 7: {
|
|
initLineSetting()
|
|
outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
|
direction = 'south'
|
|
|
|
outerLines.forEach((line) => {
|
|
setSouthAndNorthRoof(line)
|
|
if (outerLines[0].direction === 'bottom') {
|
|
if (line.direction === 'right') {
|
|
line.attributes = {
|
|
offset: eavesOffset / 10,
|
|
pitch: pitchRef.current,
|
|
type: LINE_TYPE.WALLLINE.EAVES,
|
|
}
|
|
}
|
|
|
|
if (line.direction === 'left') {
|
|
line.attributes = {
|
|
offset: shedWidth / 10,
|
|
pitch: pitchRef.current,
|
|
type: LINE_TYPE.WALLLINE.SHED,
|
|
}
|
|
}
|
|
} else {
|
|
if (line.direction === 'left') {
|
|
line.attributes = {
|
|
offset: eavesOffset / 10,
|
|
pitch: pitchRef.current,
|
|
type: LINE_TYPE.WALLLINE.EAVES,
|
|
}
|
|
}
|
|
|
|
if (line.direction === 'right') {
|
|
line.attributes = {
|
|
offset: shedWidth / 10,
|
|
pitch: pitchRef.current,
|
|
type: LINE_TYPE.WALLLINE.SHED,
|
|
}
|
|
}
|
|
}
|
|
|
|
// hideLine(line)
|
|
})
|
|
break
|
|
}
|
|
case 8: {
|
|
initLineSetting()
|
|
outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
|
direction = 'north'
|
|
|
|
outerLines.forEach((line) => {
|
|
setSouthAndNorthRoof(line)
|
|
|
|
if (outerLines[0].direction === 'bottom') {
|
|
if (line.direction === 'left') {
|
|
line.attributes = {
|
|
offset: eavesOffset / 10,
|
|
pitch: pitchRef.current,
|
|
type: LINE_TYPE.WALLLINE.EAVES,
|
|
}
|
|
}
|
|
|
|
if (line.direction === 'right') {
|
|
line.attributes = {
|
|
offset: shedWidth / 10,
|
|
pitch: pitchRef.current,
|
|
type: LINE_TYPE.WALLLINE.SHED,
|
|
}
|
|
}
|
|
} else {
|
|
if (line.direction === 'right') {
|
|
line.attributes = {
|
|
offset: eavesOffset / 10,
|
|
pitch: pitchRef.current,
|
|
type: LINE_TYPE.WALLLINE.EAVES,
|
|
}
|
|
}
|
|
|
|
if (line.direction === 'left') {
|
|
line.attributes = {
|
|
offset: shedWidth / 10,
|
|
pitch: pitchRef.current,
|
|
type: LINE_TYPE.WALLLINE.SHED,
|
|
}
|
|
}
|
|
}
|
|
|
|
// hideLine(line)
|
|
})
|
|
break
|
|
}
|
|
}
|
|
|
|
// 기존 wallLine, roofBase 제거
|
|
canvas
|
|
.getObjects()
|
|
.filter((obj) => obj.name === POLYGON_TYPE.WALL)
|
|
.forEach((line) => {
|
|
canvas.remove(line)
|
|
})
|
|
|
|
canvas
|
|
.getObjects()
|
|
.filter((obj) => obj.name === POLYGON_TYPE.ROOF)
|
|
.forEach((obj) => {
|
|
canvas.remove(...obj.innerLines)
|
|
canvas.remove(obj)
|
|
})
|
|
|
|
const polygon = addPolygonByLines(outerLines, { name: POLYGON_TYPE.WALL, direction })
|
|
polygon.lines = [...outerLines]
|
|
|
|
addPitchTextsByOuterLines()
|
|
const roof = drawRoofPolygon(polygon)
|
|
|
|
canvas?.renderAll()
|
|
roof.drawHelpLine()
|
|
// setShowRoofShapeSettingModal(false)
|
|
isFixRef.current = true
|
|
closePopup(id)
|
|
}
|
|
|
|
const initLineSetting = () => {
|
|
const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
|
|
|
const tempPolygon = addPolygonByLines(outerLines)
|
|
tempPolygon.lines.forEach((line) => {
|
|
outerLines.forEach((outerLine) => {
|
|
if (
|
|
(line.startPoint === outerLine.startPoint && line.endPoint === outerLine.endPoint) ||
|
|
(line.startPoint === outerLine.endPoint && line.endPoint === outerLine.startPoint)
|
|
) {
|
|
outerLine.direction = line.direction
|
|
outerLine.idx = line.idx
|
|
}
|
|
})
|
|
})
|
|
|
|
// 첫번째 line의 방향이 right일 경우
|
|
if (outerLines[0].direction === 'right') {
|
|
// top과 bottom의 방향을 바꾼다.
|
|
outerLines.forEach((line) => {
|
|
if (line.direction === 'top') {
|
|
line.direction = 'bottom'
|
|
} else if (line.direction === 'bottom') {
|
|
line.direction = 'top'
|
|
}
|
|
})
|
|
}
|
|
canvas.remove(tempPolygon)
|
|
}
|
|
|
|
// 동, 서 선택 시 가로라인을 케라바로 설정
|
|
const setWestAndEastRoof = (line) => {
|
|
if (line.direction === 'left' || line.direction === 'right') {
|
|
line.attributes = {
|
|
offset: gableOffset / 10,
|
|
type: LINE_TYPE.WALLLINE.GABLE,
|
|
}
|
|
}
|
|
}
|
|
|
|
// 남, 북 선택 시 세로라인을 케라바로 설정
|
|
const setSouthAndNorthRoof = (line) => {
|
|
if (line.direction === 'top' || line.direction === 'bottom') {
|
|
line.attributes = {
|
|
offset: gableOffset / 10,
|
|
type: LINE_TYPE.WALLLINE.GABLE,
|
|
}
|
|
}
|
|
}
|
|
|
|
const saveRidge = () => {
|
|
// 용마루 저장
|
|
const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
|
|
|
outerLines.forEach((line) => {
|
|
line.attributes = {
|
|
offset: eavesOffset / 10,
|
|
pitch: pitchRef.current,
|
|
type: LINE_TYPE.WALLLINE.EAVES,
|
|
}
|
|
// hideLine(line)
|
|
})
|
|
|
|
return outerLines
|
|
}
|
|
|
|
// 패턴 A : 가로선이 모두 케라바
|
|
const saveAPattern = () => {
|
|
const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
|
|
|
outerLines.forEach((line) => {
|
|
if (line.direction === 'left' || line.direction === 'right') {
|
|
line.attributes = {
|
|
offset: gableOffset / 10,
|
|
type: LINE_TYPE.WALLLINE.GABLE,
|
|
}
|
|
} else if (line.direction === 'top' || line.direction === 'bottom') {
|
|
line.attributes = {
|
|
offset: eavesOffset / 10,
|
|
pitch: pitchRef.current,
|
|
type: LINE_TYPE.WALLLINE.EAVES,
|
|
}
|
|
}
|
|
// hideLine(line)
|
|
})
|
|
|
|
return outerLines
|
|
}
|
|
|
|
// 패턴 B : 세로선이 모두 케라바
|
|
const saveBPattern = () => {
|
|
const outerLines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
|
|
|
outerLines.forEach((line) => {
|
|
if (line.direction === 'top' || line.direction === 'bottom') {
|
|
line.attributes = {
|
|
offset: gableOffset / 10,
|
|
type: LINE_TYPE.WALLLINE.GABLE,
|
|
}
|
|
} else if (line.direction === 'left' || line.direction === 'right') {
|
|
line.attributes = {
|
|
offset: eavesOffset / 10,
|
|
pitch: pitchRef.current,
|
|
type: LINE_TYPE.WALLLINE.EAVES,
|
|
}
|
|
}
|
|
// hideLine(line)
|
|
})
|
|
|
|
return outerLines
|
|
}
|
|
|
|
// 변별로 설정 팝업 내 적용
|
|
const handleConfirm = () => {
|
|
const selectedLine = canvas?.getActiveObject()
|
|
if (!selectedLine) {
|
|
return
|
|
}
|
|
|
|
let attributes
|
|
switch (buttonAct) {
|
|
case 1: {
|
|
// 처마
|
|
attributes = {
|
|
type: LINE_TYPE.WALLLINE.EAVES,
|
|
pitch: pitchRef.current,
|
|
offset: eavesOffset / 10,
|
|
}
|
|
addPitchText(currentObject)
|
|
selectedLine.set({ strokeWidth: 4 })
|
|
selectedLine.set({ stroke: '#45CD7D' })
|
|
break
|
|
}
|
|
case 2: {
|
|
// 케라바
|
|
attributes = {
|
|
type: LINE_TYPE.WALLLINE.GABLE,
|
|
offset: gableOffset / 10,
|
|
}
|
|
selectedLine.set({ strokeWidth: 4 })
|
|
selectedLine.set({ stroke: '#3FBAE6' })
|
|
break
|
|
}
|
|
case 3: {
|
|
// 벽
|
|
attributes = {
|
|
type: LINE_TYPE.WALLLINE.WALL,
|
|
width: hasSleeve === '0' ? 0 : sleeveOffset / 10,
|
|
sleeve: hasSleeve === '1',
|
|
}
|
|
break
|
|
}
|
|
case 4: {
|
|
// 팔작지붕
|
|
attributes = {
|
|
type: LINE_TYPE.WALLLINE.HIPANDGABLE,
|
|
pitch: pitchRef.current,
|
|
offset: eavesOffset / 10,
|
|
width: hipAndGableWidth / 10,
|
|
}
|
|
addPitchText(currentObject)
|
|
selectedLine.set({ strokeWidth: 4 })
|
|
selectedLine.set({ stroke: '#45CD7D' })
|
|
break
|
|
}
|
|
case 5: {
|
|
// 반절처
|
|
attributes = {
|
|
type: LINE_TYPE.WALLLINE.JERKINHEAD,
|
|
offset: gableOffset / 10,
|
|
width: jerkinHeadWidth / 10,
|
|
pitch: jerkinHeadPitchRef.current,
|
|
}
|
|
addPitchText(currentObject)
|
|
selectedLine.set({ strokeWidth: 4 })
|
|
selectedLine.set({ stroke: '#3FBAE6' })
|
|
break
|
|
}
|
|
case 6: {
|
|
// 한쪽흐름
|
|
attributes = {
|
|
type: LINE_TYPE.WALLLINE.SHED,
|
|
pitch: shedPitchRef.current,
|
|
width: shedWidth / 10,
|
|
}
|
|
addPitchText(currentObject)
|
|
selectedLine.set({ strokeWidth: 4 })
|
|
selectedLine.set({ stroke: '#000000' })
|
|
break
|
|
}
|
|
}
|
|
selectedLine.attributes = attributes
|
|
history.current.push(selectedLine)
|
|
canvas.renderAll()
|
|
nextLineFocus(selectedLine)
|
|
}
|
|
|
|
const nextLineFocus = (selectedLine) => {
|
|
const lines = canvas.getObjects().filter((obj) => obj.name === 'outerLine')
|
|
const index = lines.findIndex((line) => line.idx === selectedLine.idx)
|
|
|
|
const nextLine = lines[index + 1] || lines[0]
|
|
canvas.setActiveObject(nextLine)
|
|
}
|
|
|
|
// 변별로 설정 내 일변 전으로 돌아가기
|
|
const handleRollBack = () => {
|
|
if (history.current.length === 0) {
|
|
return
|
|
}
|
|
const lastLine = history.current.pop()
|
|
|
|
currentObject.set({
|
|
stroke: '#000000',
|
|
strokeWidth: 4,
|
|
})
|
|
|
|
lastLine.set({
|
|
stroke: '#000000',
|
|
strokeWidth: 4,
|
|
})
|
|
|
|
canvas.setActiveObject(lastLine)
|
|
canvas.renderAll()
|
|
}
|
|
|
|
return {
|
|
shapeNum,
|
|
setShapeNum,
|
|
shapeMenu,
|
|
handleSave,
|
|
buttonMenu,
|
|
pitch,
|
|
setPitch,
|
|
eavesOffset,
|
|
setEavesOffset,
|
|
gableOffset,
|
|
setGableOffset,
|
|
sleeveOffset,
|
|
setSleeveOffset,
|
|
jerkinHeadWidth,
|
|
setJerkinHeadWidth,
|
|
jerkinHeadPitch,
|
|
setJerkinHeadPitch,
|
|
hipAndGableWidth,
|
|
setHipAndGableWidth,
|
|
shedWidth,
|
|
setShedWidth,
|
|
hasSleeve,
|
|
setHasSleeve,
|
|
buttonAct,
|
|
setButtonAct,
|
|
handleConfirm,
|
|
handleRollBack,
|
|
pitchText,
|
|
shedPitch,
|
|
setShedPitch,
|
|
}
|
|
}
|