From 1e9b5236859400d0203c0f41643f20ec32073f79 Mon Sep 17 00:00:00 2001 From: ChenX Date: Wed, 2 Jan 2019 14:47:54 +0800 Subject: [PATCH] =?UTF-8?q?!228=20=E9=97=A8=E6=9D=BF=E9=83=A8=E5=88=86?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=E5=92=8C=E6=8A=BD=E5=B1=89UI=20Merge=20pull?= =?UTF-8?q?=20request=20!228=20from=20ZoeLeeFZ/door5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Add-on/DrawBoard/DrawBoardServer.ts | 25 -- src/Add-on/DrawBoard/DrawBoardTool.ts | 1 - src/Add-on/DrawBoard/DrawDoor.ts | 120 +++++- src/Add-on/DrawBoard/DrawDoorBoard.ts | 0 src/Add-on/DrawBoard/DrawDrawer.ts | 36 ++ src/Add-on/DrawDrilling/DrawDrillingTool.ts | 4 +- src/Common/CheckoutVaildValue.ts | 27 +- src/Editor/CommandRegister.ts | 4 +- src/Geometry/Box.ts | 5 - src/UI/Components/Board/BehindBoardModal.tsx | 4 +- src/UI/Components/Board/BoardCommon.tsx | 179 +++++--- src/UI/Components/Board/BoardModal.tsx | 1 + src/UI/Components/Board/BoardProcessModal.tsx | 44 +- .../Components/Board/Door/DoorConfigModal.tsx | 355 ++++++++++++++++ src/UI/Components/Board/Door/DoorModal.tsx | 85 ++++ .../Board/Door/DoorPreviewComponent.tsx | 55 +++ .../Components/Board/Door/DoorPreviewItem.tsx | 387 ++++++++++++++++++ src/UI/Components/Board/DoorModal.tsx | 62 --- src/UI/Components/Board/GangDrillModal.tsx | 2 +- src/UI/Components/Board/UserConfig.tsx | 23 +- .../Modal/ModalStyle/BoardModal.less | 2 +- .../Modal/ModalStyle/DoorModal.less | 145 +++++++ src/UI/Components/Modal/ModalStyle/Modal.less | 3 +- src/UI/Components/Modal/ModalsManage.tsx | 1 + src/UI/Components/RightPanel/RightPanel.tsx | 4 +- src/UI/Components/Toaster.tsx | 11 +- src/UI/Css/style.less | 16 +- src/UI/Store/BoardStore.ts | 4 - .../Store/DoorDrawerStore/DoorDrawerStore.ts | 225 ++++++++++ src/UI/Store/DoorDrawerStore/DoorStore.ts | 141 +++++++ src/UI/Store/DoorDrawerStore/DrawerStore.ts | 73 ++++ src/UI/Store/DoorInterface.ts | 109 +++++ src/UI/Store/DrillStore.ts | 2 +- .../Board => Store}/drillInterface.ts | 0 34 files changed, 1945 insertions(+), 210 deletions(-) delete mode 100644 src/Add-on/DrawBoard/DrawBoardServer.ts delete mode 100644 src/Add-on/DrawBoard/DrawDoorBoard.ts create mode 100644 src/Add-on/DrawBoard/DrawDrawer.ts create mode 100644 src/UI/Components/Board/Door/DoorConfigModal.tsx create mode 100644 src/UI/Components/Board/Door/DoorModal.tsx create mode 100644 src/UI/Components/Board/Door/DoorPreviewComponent.tsx create mode 100644 src/UI/Components/Board/Door/DoorPreviewItem.tsx delete mode 100644 src/UI/Components/Board/DoorModal.tsx create mode 100644 src/UI/Components/Modal/ModalStyle/DoorModal.less create mode 100644 src/UI/Store/DoorDrawerStore/DoorDrawerStore.ts create mode 100644 src/UI/Store/DoorDrawerStore/DoorStore.ts create mode 100644 src/UI/Store/DoorDrawerStore/DrawerStore.ts create mode 100644 src/UI/Store/DoorInterface.ts rename src/UI/{Components/Board => Store}/drillInterface.ts (100%) diff --git a/src/Add-on/DrawBoard/DrawBoardServer.ts b/src/Add-on/DrawBoard/DrawBoardServer.ts deleted file mode 100644 index eab3cea7b..000000000 --- a/src/Add-on/DrawBoard/DrawBoardServer.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { commandMachine } from "../../Editor/CommandMachine"; -import { CommandState } from "../../Editor/CommandState"; - -export class DrawBoardServer -{ - static m_DrawMap: Map = new Map(); - static AddDrawBoardCmd(type, Callback) - { - if (!this.m_DrawMap.has(type)) - this.m_DrawMap.set(type, Callback); - } - static async ExecDrawBoardCmd(type) - { - if (this.m_DrawMap.has(type)) - { - if (CommandState.CommandIng) - return; - - commandMachine.CommandStart(type); - await this.m_DrawMap.get(type)(); - commandMachine.CommandEnd(type); - } - } - -} diff --git a/src/Add-on/DrawBoard/DrawBoardTool.ts b/src/Add-on/DrawBoard/DrawBoardTool.ts index 9f8d46e8a..5ec86237b 100644 --- a/src/Add-on/DrawBoard/DrawBoardTool.ts +++ b/src/Add-on/DrawBoard/DrawBoardTool.ts @@ -1,6 +1,5 @@ import { Matrix4 } from 'three'; import { app } from '../../ApplicationServices/Application'; -import { Singleton } from '../../Common/Singleton'; import { BoardType } from '../../DatabaseServices/Board'; import { Command } from '../../Editor/CommandMachine'; import { PromptStatus } from '../../Editor/PromptResult'; diff --git a/src/Add-on/DrawBoard/DrawDoor.ts b/src/Add-on/DrawBoard/DrawDoor.ts index 94d1f967e..d7f1d8182 100644 --- a/src/Add-on/DrawBoard/DrawDoor.ts +++ b/src/Add-on/DrawBoard/DrawDoor.ts @@ -1,17 +1,127 @@ +import { toJS } from "mobx"; +import { Vector3 } from "three"; import { app } from "../../ApplicationServices/Application"; +import { ToFixed } from "../../Common/Utils"; +import { Board, BoardType } from "../../DatabaseServices/Board"; import { Command } from "../../Editor/CommandMachine"; -import { DoorModal } from "../../UI/Components/Board/DoorModal"; +import { MoveMatrix } from "../../Geometry/GeUtils"; +import { PointSelectSpaceClamp } from "../../Geometry/SpaceParse/PointSelectSpaceClamp"; +import { DoorModal } from "../../UI/Components/Board/Door/DoorModal"; import { ModalPosition, ModalState } from "../../UI/Components/Modal/ModalsManage"; -import { DoorStore } from "../../UI/Store/BoardStore"; +import { DoorStore, openDirTitle } from "../../UI/Store/DoorDrawerStore/DoorStore"; +import { DoorOpenDir } from "../../UI/Store/DoorInterface"; export class DrawDoor implements Command { async exec() { - let store = DoorStore.GetInstance(); - app.m_Editor.m_ModalManage.RenderModeless(DoorModal, ModalPosition.Center, { store }); + let selectSpace = new PointSelectSpaceClamp(); + await selectSpace.Select(); + if (!selectSpace.ParseOK) + return; + + let spaceParse = selectSpace.m_SpaceParse; + let size = spaceParse.Size; + + let store = DoorStore.GetInstance() as DoorStore; + store.m_Option.boardName = spaceParse.m_Boards[0].BoardProcessOption.cabinetName; + store.totalHeight = parseFloat(ToFixed(size.z, 2)); + store.totalWidth = parseFloat(ToFixed(size.x, 2)); + store.totalDepth = parseFloat(ToFixed(size.y, 2)); + store.m_Option.depth = store.totalDepth; + + app.m_Editor.m_ModalManage.RenderModal(DoorModal, ModalPosition.Center, { store }); let state = await app.m_Editor.m_ModalManage.Wait(); - if (state !== ModalState.Ok) return; + if (state === ModalState.Ok) + { + let min = spaceParse.m_SpaceBox.min; + + store.doorPosition.copy(min); + store.CalcDoorsInfo(true); + + let row = store.m_Option.row; + let col = store.m_Option.col; + let doorThickness = store.m_Option.doorThickness; + let midSpace = store.m_Option.midSpace; + + //门板信息排序从左下角那块板开始 + let doorInfos = toJS(store.doorsInfo); + doorInfos.sort((inf1, inf2) => + { + if (inf1.row !== inf2.row) + return inf2.row - inf1.row; + else + return inf1.col - inf2.col; + }) + + //第一块门板起始位置 + let startPt = store.doorPosition; + //x,z方向移动距离 + let xDist = 0; + let ZDist = 0; + let thickness = store.m_Option.thickness; + + //立板深度减去偏移距离 + let depth = store.m_Option.depth; + let offset = store.m_Option.offset; + if (offset > 0) + depth -= offset; + + for (let info of doorInfos) + { + let brs: Board[] = []; + if (info.col === 0) + { + xDist = 0; + } + let door = Board.CreateBoard(info.height, info.width, doorThickness, BoardType.Behind); + let vec = startPt.clone(); + door.Name = + info.openDir === DoorOpenDir.None ? "门板" : + openDirTitle[info.openDir] + "开门板"; + + vec.x += xDist + midSpace * info.col; + xDist += info.width; + + vec.z += ZDist + midSpace * (row - info.row - 1); + if (info.col === col - 1) + ZDist += info.height; + + door.ApplyMatrix(MoveMatrix(vec)); + brs.push(door); + + //门板外偏移,修正层板和立板位置 + if (offset < 0) + vec.add(new Vector3(0, -offset)); + //是否绘制层板 + if (info.isDrawLayer) + { + let len = size.x; + let br = Board.CreateBoard(len, depth, thickness, BoardType.Layer); + let v = vec.clone(); + v.setX(min.x); + v.add(new Vector3(len, doorThickness, (thickness - midSpace) / 2)); + br.ApplyMatrix(MoveMatrix(v)); + brs.push(br); + } + //是否绘制立板 + if (info.isDrawVer) + { + let len = size.z; + let br = Board.CreateBoard(len, depth, thickness, BoardType.Vertical); + vec.setZ(min.z); + vec.add(new Vector3(info.width + (thickness + midSpace) / 2, doorThickness)); + br.ApplyMatrix(MoveMatrix(vec)); + brs.push(br); + } + + for (let br of brs) + { + br.ApplyMatrix(spaceParse.m_SpaceOCS); + app.m_Database.ModelSpace.Append(br); + } + } + } } } diff --git a/src/Add-on/DrawBoard/DrawDoorBoard.ts b/src/Add-on/DrawBoard/DrawDoorBoard.ts deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/Add-on/DrawBoard/DrawDrawer.ts b/src/Add-on/DrawBoard/DrawDrawer.ts new file mode 100644 index 000000000..44bbfe380 --- /dev/null +++ b/src/Add-on/DrawBoard/DrawDrawer.ts @@ -0,0 +1,36 @@ +import { app } from "../../ApplicationServices/Application"; +import { FixedNotZero } from "../../Common/Utils"; +import { Command } from "../../Editor/CommandMachine"; +import { PointSelectSpaceClamp } from "../../Geometry/SpaceParse/PointSelectSpaceClamp"; +import { DoorModal } from "../../UI/Components/Board/Door/DoorModal"; +import { ModalPosition, ModalState } from "../../UI/Components/Modal/ModalsManage"; +import { DrawerStore } from "../../UI/Store/DoorDrawerStore/DrawerStore"; + +export class DrawDrawrer implements Command +{ + async exec() + { + let selectSpace = new PointSelectSpaceClamp(); + await selectSpace.Select(); + if (!selectSpace.ParseOK) + return; + + let spaceParse = selectSpace.m_SpaceParse; + let size = spaceParse.Size; + + let store = DrawerStore.GetInstance() as DrawerStore; + store.m_Option.boardName = spaceParse.m_Boards[0].BoardProcessOption.cabinetName; + store.totalHeight = parseFloat(FixedNotZero(size.z, 2)); + store.totalWidth = parseFloat(FixedNotZero(size.x, 2)); + store.totalDepth = parseFloat(FixedNotZero(size.y, 2)); + store.m_Option.depth = store.totalDepth; + + app.m_Editor.m_ModalManage.RenderModal(DoorModal, ModalPosition.Center, { store }); + let state = await app.m_Editor.m_ModalManage.Wait(); + + if (state === ModalState.Ok) + { + //TODO:实现绘制抽屉 + } + } +} diff --git a/src/Add-on/DrawDrilling/DrawDrillingTool.ts b/src/Add-on/DrawDrilling/DrawDrillingTool.ts index 0d120d98f..d3b3d1e46 100644 --- a/src/Add-on/DrawDrilling/DrawDrillingTool.ts +++ b/src/Add-on/DrawDrilling/DrawDrillingTool.ts @@ -9,9 +9,9 @@ import { ObjectId } from "../../DatabaseServices/ObjectId"; import { CollisionDetection } from "../../Geometry/DrillParse/CollisionDetection"; import { Face } from "../../Geometry/DrillParse/Face"; import { cZAxis, equaln, MoveMatrix } from "../../Geometry/GeUtils"; -import { DrillingOption, SpacingType } from "../../UI/Components/Board/drillInterface"; -import { FaceDirection } from "../../UI/Store/BoardInterface"; +import { DrillingOption, SpacingType } from "../../UI/Store/drillInterface"; import { DrillStore } from "../../UI/Store/DrillStore"; +import { FaceDirection } from "../../UI/Store/BoardInterface"; export class DrawDrillingTool extends Singleton { diff --git a/src/Common/CheckoutVaildValue.ts b/src/Common/CheckoutVaildValue.ts index 65ed06d74..d23bf163a 100644 --- a/src/Common/CheckoutVaildValue.ts +++ b/src/Common/CheckoutVaildValue.ts @@ -5,6 +5,7 @@ export enum CheckObjectType BR = "board", DR = "drill", AR = "array", + Do = "door", } export namespace CheckoutValid @@ -21,6 +22,12 @@ export namespace CheckoutValid return !Object.keys(obj).every(k => CheckoutArrayOption(k, obj[k]) === "" ) + case CheckObjectType.Do: + return !Object.keys(obj).every(k => + CheckoutDoorOption(k, obj[k]) === "" + ) + default: + return true; } } export function CheckOption(type: CheckObjectType, k: string, v: string) @@ -33,6 +40,8 @@ export namespace CheckoutValid return CheckoutDrillOption(k, v); case CheckObjectType.AR: return CheckoutArrayOption(k, v); + case CheckObjectType.Do: + return CheckoutDoorOption(k, v); } } export function CheckoutBoardOption(k: string, v: string): string @@ -67,7 +76,8 @@ export namespace CheckoutValid case "sealedDown": case "sealedLeft": case "sealedRight": - if (!isNaN(parseFloat(v)) && parseFloat(v) <= 0) return "数值必须大于0"; + if (!isNaN(parseFloat(v)) && parseFloat(v) <= 0) + return "数值必须大于0"; default: if (v === "" || isNaN(Number(v))) { @@ -160,4 +170,19 @@ export namespace CheckoutValid } return ""; } + export function CheckoutDoorOption(k: string, v: string): string + { + switch (k) + { + case "row": + case "col": + let val = Number(v); + if (!isNaN(val) && val !== Math.floor(val)) + { + return "数值必须1~20整数" + } + default: + return CheckoutBoardOption(k, v) + } + } } diff --git a/src/Editor/CommandRegister.ts b/src/Editor/CommandRegister.ts index 23670be27..de383b28c 100644 --- a/src/Editor/CommandRegister.ts +++ b/src/Editor/CommandRegister.ts @@ -98,6 +98,7 @@ import { ZoomE } from "../Add-on/ZoomE"; import { CommandServer } from '../DatabaseServices/CommandServer'; import { ICommand } from '../UI/Components/CommandPanel/CommandList'; import { commandMachine } from './CommandMachine'; +import { DrawDrawrer } from '../Add-on/DrawBoard/DrawDrawer'; export function registerCommand() @@ -228,7 +229,7 @@ export function registerCommand() commandMachine.RegisterCommand("lb", new DrawVerticalBoard()); commandMachine.RegisterCommand("db", new DrawSingleBoard()); commandMachine.RegisterCommand("skt", new DrawClosingStrip()); - commandMachine.RegisterCommand("mb", new DrawDoor()); + commandMachine.RegisterCommand("door", new DrawDoor()); commandMachine.RegisterCommand("drillconfig", new DrillConfig()); commandMachine.RegisterCommand("pz", new DrawDrilling()); commandMachine.RegisterCommand("yx", new DrawSpecialShapedBoard()); @@ -236,6 +237,7 @@ export function registerCommand() commandMachine.RegisterCommand("qg", new LinearCutting()); commandMachine.RegisterCommand("qg2", new NonAssociativeCutting()); + commandMachine.RegisterCommand("drawer", new DrawDrawrer()); //修改颜色命令 for (let i = 0; i < 24; i++) diff --git a/src/Geometry/Box.ts b/src/Geometry/Box.ts index 28ad61278..e38d1defd 100644 --- a/src/Geometry/Box.ts +++ b/src/Geometry/Box.ts @@ -30,7 +30,6 @@ export class Box3Ext extends Box3 { return this.getSize(new Vector3()).toArray().every(x => x > minSize); } - substract(b: Box3Ext, spaceType: SplitType) { let interBox = this.clone().intersect(b) as this; @@ -57,8 +56,4 @@ export class Box3Ext extends Box3 interBox.max.setComponent(splitType, Math.max(this.min.getComponent(splitType), b2.min.getComponent(splitType))); return interBox; } - isIntersect(b: Box3) - { - return this.intersectsBox(b) && (this.clone().intersect(b) as this).Volume > 0; - } } diff --git a/src/UI/Components/Board/BehindBoardModal.tsx b/src/UI/Components/Board/BehindBoardModal.tsx index 37e1a52f0..d3579b55d 100644 --- a/src/UI/Components/Board/BehindBoardModal.tsx +++ b/src/UI/Components/Board/BehindBoardModal.tsx @@ -4,7 +4,7 @@ import { observer } from 'mobx-react'; import * as React from 'react'; import { BehindHeightPositon, BrRelativePos } from '../../Store/BoardInterface'; import { BehindBoardStore } from '../../Store/BoardStore'; -import { BoardModel, ItemName, SetBoardDataBlock, SetBoardDataItem, BoardRePosBlock } from './BoardCommon'; +import { BoardDirectionIcon, ItemName, SetBoardDataBlock, SetBoardDataItem, BoardRePosBlock } from './BoardCommon'; import { CheckObjectType } from '../../../Common/CheckoutVaildValue'; @observer @@ -111,7 +111,7 @@ export class BehindBoardModal extends React.Component<{ store?: BehindBoardStore option={store.m_Option} uiOption={store.UIOption} inline={true} /> - + void; + onChange?: (e) => void; inline?: boolean; + className?: string; } interface ISetBlockOption { @@ -29,6 +30,7 @@ interface ISetBlockOption uiOption?: Object; className?: string; isInline?: boolean; + onChange?: Function; } interface TBProps { @@ -51,7 +53,7 @@ export class SetBoardDataItem extends React.Component { const props = this.props; return ( -
+
{props.title}: @@ -75,65 +77,70 @@ export const SetBoardDataBlock = observer( option={props.option} uiOption={props.uiOption} title={v} + onChange={() => + { + if (props.onChange) + props.onChange(); + }} /> ) }
); -export const TBBoardDataBlock = - observer( - (props: TBProps) => - { - return ( -
- props.option.isDraw = !props.option.isDraw} - /> - props.option.isWrapSide = e.currentTarget.value === "1"} - selectedValue={props.option.isWrapSide ? "1" : "0"} - > - - - -
+export const TBBoardDataBlock = observer( + (props: TBProps) => + { + return ( +
+ - { - if (k === "offset" && !props.istop) - v = "下留" - return ( - - ) - }) + fontSize: "1.4rem", + fontWeight: 600 } -
+ } + checked={props.option.isDraw} + label={props.istop ? "顶板" : "底板"} + onChange={() => props.option.isDraw = !props.option.isDraw} + /> + props.option.isWrapSide = e.currentTarget.value === "1"} + selectedValue={props.option.isWrapSide ? "1" : "0"} + > + + + +
+ { + props.pars.map(([k, v]) => + { + if (k === "offset" && !props.istop) + v = "下留" + return ( + + ) + }) + }
- ) - }); - +
+ ) + } +); -export const BoardModel = () => +/* 显示板件的方向(封边使用) */ +export const BoardDirectionIcon = () => ) + +interface I5InputComponent extends ISetItemOption +{ + showDirectionIcon: boolean; //显示中间那个模型 + hasCenter: boolean; //是否有中心输入框 + upKey: string; //上下左右中的key + downKey: string; + leftKey: string; + rightKey: string; + centerKey?: string; +} + +/** + * 一圈输入框 + */ +@observer +export class Input5Or4Component extends React.Component +{ + render() + { + return ( +
+ +
+ + { + this.props.showDirectionIcon && + } + { + this.props.hasCenter && + } + +
+ +
+ ) + } +} diff --git a/src/UI/Components/Board/BoardModal.tsx b/src/UI/Components/Board/BoardModal.tsx index ca3348044..c4414c55c 100644 --- a/src/UI/Components/Board/BoardModal.tsx +++ b/src/UI/Components/Board/BoardModal.tsx @@ -29,6 +29,7 @@ export enum BoardModalType Skt = "skt",//收口条 Dr = "dr",//排钻 Zx = "zx", //造型 + Mb = "mb", // 门板 } export interface BoardModalProps { diff --git a/src/UI/Components/Board/BoardProcessModal.tsx b/src/UI/Components/Board/BoardProcessModal.tsx index d1eb38d17..6ddbe4e99 100644 --- a/src/UI/Components/Board/BoardProcessModal.tsx +++ b/src/UI/Components/Board/BoardProcessModal.tsx @@ -1,14 +1,13 @@ import { Classes, HTMLSelect } from '@blueprintjs/core'; +import { IObservableValue } from 'mobx'; import { observer } from 'mobx-react'; import * as React from 'react'; import { CheckObjectType } from '../../../Common/CheckoutVaildValue'; import { Board } from '../../../DatabaseServices/Board'; +import { Circle } from '../../../DatabaseServices/Circle'; import { BoardProcessOption, ComposingType, DrillType, LinesType, FaceDirection } from '../../Store/BoardInterface'; -import { ToasterInput } from '../Toaster'; -import { BoardModel, SetBoardDataBlock, SetBoardDataItem } from './BoardCommon'; +import { Input5Or4Component, SetBoardDataBlock, SetBoardDataItem } from './BoardCommon'; import { EdgeSealingComponent } from './EdgeSealingComponent'; -import { Circle } from '../../../DatabaseServices/Circle'; -import { IObservableValue } from 'mobx'; interface BoardProcessProps { @@ -158,37 +157,22 @@ export class BoardProcessModal extends React.Component{
封边 { - isShowHighEditor ? ( - - ) - : null + isShowHighEditor && }
-
- -
- - - -
- -
+ }
) } diff --git a/src/UI/Components/Board/Door/DoorConfigModal.tsx b/src/UI/Components/Board/Door/DoorConfigModal.tsx new file mode 100644 index 000000000..e1b57caa0 --- /dev/null +++ b/src/UI/Components/Board/Door/DoorConfigModal.tsx @@ -0,0 +1,355 @@ +import { Checkbox, Divider, H5, H6, Radio, RadioGroup } from '@blueprintjs/core'; +import { observer } from 'mobx-react'; +import * as React from 'react'; +import { CheckObjectType } from '../../../../Common/CheckoutVaildValue'; +import { DoorDrawerStore } from '../../../Store/DoorDrawerStore/DoorDrawerStore'; +import { DoorStore } from '../../../Store/DoorDrawerStore/DoorStore'; +import { DoorPosType, HandleHorPos, HandleVePos } from '../../../Store/DoorInterface'; +import { ToasterInput } from '../../Toaster'; +import { Input5Or4Component, SetBoardDataBlock, SetBoardDataItem } from '../BoardCommon'; + +@observer +export class DoorConfigModal extends React.Component<{ store?: DoorDrawerStore }> +{ + private uiOption; + private isDoor: boolean = true; + private handleChangeDoorPosType = (e) => + { + const store = this.props.store; + store.m_Option.doorPosType = parseFloat(e.currentTarget.value) as DoorPosType; + if (store.m_Option.doorPosType === DoorPosType.In) + { + store.m_Option.offset = 18; + store.m_Option.topExt = 0; + store.m_Option.bottomExt = 0; + store.m_Option.leftExt = 0; + store.m_Option.rightExt = 0; + this.uiOption["offset"] = "18"; + this.uiOption["topExt"] = "0"; + this.uiOption["bottomExt"] = "0"; + this.uiOption["leftExt"] = "0"; + this.uiOption["rightExt"] = "0"; + } + else + { + store.m_Option.offset = 0; + store.m_Option.topExt = 18; + store.m_Option.bottomExt = 18; + store.m_Option.leftExt = 18; + store.m_Option.rightExt = 18; + this.uiOption["offset"] = "0"; + this.uiOption["topExt"] = "18"; + this.uiOption["bottomExt"] = "18"; + this.uiOption["leftExt"] = "18"; + this.uiOption["rightExt"] = "18"; + } + store.CalcDoorsInfo(true); + } + componentWillMount() + { + this.uiOption = this.props.store.UIOption; + this.isDoor = this.props.store instanceof DoorStore; + } + render() + { + const store = this.props.store; + return ( + <> +
+ + { + if (store.m_Option.col > 20) + { + store.m_Option.col = 20; + store.UIOption.col = "20"; + } + store.InitDoorInfos(); + }} + /> + + { + if (store.m_Option.row > 20) + { + store.m_Option.row = 20; + store.UIOption.row = "20"; + } + store.InitDoorInfos(); + }} + /> + +
+ + + { + if (store.m_Option.topOffset + store.m_Option.bottomOffset < store.totalHeight) + store.CalcDoorsInfo(true); + }} + /> + +
+
+ + + + + +
+
+
+
盖板延伸
+ store.CalcDoorsInfo(true)} + /> +
+
+
预留间隙
+ store.CalcDoorsInfo(true)} + /> +
+
+
+ +
+ + + + { + store.m_Option.isAuto = !store.m_Option.isAuto; + if (store.m_Option.isAuto) + { + store.m_Option.depth = store.totalDepth; + this.uiOption.depth = store.totalDepth.toString(); + } + }} + /> + { + !this.isDoor && + } +
+ +
+ + { + this.isDoor && + } + +
+ + { + this.isDoor &&
+
+
层板立板封边
+ +
+
+
门板封边
+ +
+
+ } +
拉手
+
+ +
+ + { + store.m_Option.handleHorPos = parseFloat(e.currentTarget.value) as HandleHorPos; + }} + > + + + + + +
+
+ + { + store.m_Option.handleVePos = parseFloat(e.currentTarget.value) as HandleVePos; + }} + > + + + + + +
+
+ { + this.isDoor ? <> +
铰链
+ + : <> +
轨道
+
+ + store.m_Option["isAutoSelectTrack"] = !store.m_Option["isAutoSelectTrack"]} + /> +
+ + } + + ) + } +} diff --git a/src/UI/Components/Board/Door/DoorModal.tsx b/src/UI/Components/Board/Door/DoorModal.tsx new file mode 100644 index 000000000..5057227d2 --- /dev/null +++ b/src/UI/Components/Board/Door/DoorModal.tsx @@ -0,0 +1,85 @@ +import { inject, observer } from 'mobx-react'; +import * as React from 'react'; +import { Button, Classes, Icon, H5 } from '@blueprintjs/core'; +import { ModalState } from '../../Modal/ModalsManage'; +import { DoorConfigModal } from './DoorConfigModal'; +import { DoorPreviewComponent } from './DoorPreviewComponent'; +import { UserConfig } from '../UserConfig'; +import { BoardModalType } from '../BoardModal'; +import { DoorDrawerStore } from '../../../Store/DoorDrawerStore/DoorDrawerStore'; +import { AppToaster } from '../../Toaster'; + +@inject("store") +@observer +export class DoorModal extends React.Component<{ store?: DoorDrawerStore }, {}> +{ + render() + { + let store = this.props.store; + return ( +
+
+
+ +

{store.title}设计

+
+
+
+
+ +
+
+ +
+
+
板件属性
+
拉手参数
+
铰链参数
+
+
+
+
+ +
+
+
+
+
+ ); + } +} diff --git a/src/UI/Components/Board/Door/DoorPreviewComponent.tsx b/src/UI/Components/Board/Door/DoorPreviewComponent.tsx new file mode 100644 index 000000000..5eb0b09e3 --- /dev/null +++ b/src/UI/Components/Board/Door/DoorPreviewComponent.tsx @@ -0,0 +1,55 @@ +import { observer } from 'mobx-react'; +import * as React from 'react'; +import { DoorPreviewItem, DoorPreviewSmItem, DoorPreviewLgItem } from './DoorPreviewItem'; +import { DoorDrawerStore } from '../../../Store/DoorDrawerStore/DoorDrawerStore'; +import { DrawerStore } from '../../../Store/DoorDrawerStore/DrawerStore'; + +@observer +export class DoorPreviewComponent extends React.Component<{ store?: DoorDrawerStore }> +{ + componentDidMount() + { + this.props.store.InitDoorInfos(); + } + render() + { + const store = this.props.store; + let refSize = 80; + if (store instanceof DrawerStore) + refSize = 100; + + return ( + <> +
+ 总宽:{store.totalWidth}mm + 总深:{store.totalDepth}mm + 总高:{store.totalHeight}mm +
+
+ { + if (el) + store.previewEl = el; + }} + className="pre-canvas"> + { + store.doorsInfo.map(info => + { + return ( + + ) + }) + } +
+ + ) + } +} diff --git a/src/UI/Components/Board/Door/DoorPreviewItem.tsx b/src/UI/Components/Board/Door/DoorPreviewItem.tsx new file mode 100644 index 000000000..b748be00a --- /dev/null +++ b/src/UI/Components/Board/Door/DoorPreviewItem.tsx @@ -0,0 +1,387 @@ +import { Button, Checkbox, Classes, HTMLSelect, InputGroup, Popover, Radio, RadioGroup } from '@blueprintjs/core'; +import { observable } from 'mobx'; +import { observer } from 'mobx-react'; +import * as React from 'react'; +import { FixedNotZero } from '../../../../Common/Utils'; +import { DoorDrawerStore } from '../../../Store/DoorDrawerStore/DoorDrawerStore'; +import { DoorStore, openDirTitle } from '../../../Store/DoorDrawerStore/DoorStore'; +import { DoorOpenDir, IDoorInfo } from "../../../Store/DoorInterface"; + +interface IDoorPreviewItemProps +{ + store: DoorDrawerStore; + info: IDoorInfo; + doorCom?: any; //渲染的门板预览UI组件 + onDbClick?: () => void; +} + +const getCalcStyles = (info: IDoorInfo, store: DoorDrawerStore): React.CSSProperties => +{ + return { + width: info.divWidth + "px", + height: info.divHeight + "px", + marginRight: info.col === store.m_Option.col - 1 ? "0" : "2px", + marginBottom: info.row === store.m_Option.row - 1 ? "0" : "2px", + } +} + +//预览图门板比较大时渲染 +@observer +export class DoorPreviewLgItem extends React.Component +{ + render() + { + const { store, info } = this.props; + const isDoor = store instanceof DoorStore; + return ( +
+ { + info.row === 0 && + +
+ ) + } + +} + +//预览图门板比较小时渲染 +@observer +export class DoorPreviewSmItem extends React.Component{ + + render() + { + const { info, store } = this.props; + const isDoor = store instanceof DoorStore; + + return ( +
+ { + isDoor && + {openDirTitle[info.openDir]} + + } + { + info.row === 0 && + {info.showWidth} + + } + { + info.col === 0 && + {info.showHeight} + + } +
e.stopPropagation()} + onClick={e => e.stopPropagation()} + onDoubleClick={e => e.stopPropagation()} + > + { + isDoor && (info.row === 0 && info.col !== store.m_Option.col - 1) && + + { + info.isDrawVer = !info.isDrawVer; + }} + /> + } + { + isDoor && (info.col === 0 && info.row !== store.m_Option.row - 1) && + + { + e.stopPropagation(); + }} + onChange={() => + { + info.isDrawLayer = !info.isDrawLayer; + }} + /> + } +
+
+ + ) + } +} + +@observer +export class DoorPreviewItem extends React.Component{ + + @observable isOpen = false; + render() + { + const { info, store } = this.props; + const isDoor = store instanceof DoorStore; + + return ( +
+ + (e.parentElement.firstElementChild as HTMLDivElement).onclick = () => + { + this.isOpen = false; + } + } + modifiers={{ + flip: { enabled: true }, + keepTogether: { enabled: true }, + preventOverflow: { enabled: true, boundariesElement: "scrollParent" } + }} + content={ +
+ {this.RenderRadiusOption(isDoor, info, store)} +
+ {this.RenderInputAndLock(info, store, isDoor)} +
+
+ } + target={ + this.isOpen = true} /> + } + > +
+
+ ) + } + + private RenderRadiusOption(isDoor: boolean, info: IDoorInfo, store: DoorDrawerStore) + { + return (isDoor && + { + info.openDir = e.currentTarget.value as DoorOpenDir; + (store as DoorStore).ChangeOpenDir(info); + }} + > + + + + + + ) + } + private RenderInputAndLock(info: IDoorInfo, store: DoorDrawerStore, isDoor: boolean): React.ReactNode + { + return (info.row === 0 || info.col === 0 || !isDoor) && + <> +
+ store.ChangeLockStatus(info, true)} /> + + { + info.isLockWidth = true; + info.showWidth = e.target.value; + }} + onBlur={e => + { + let vaildVal = parseFloat(e.currentTarget.value); + if (!isNaN(vaildVal) && info.width !== vaildVal) + { + let oldWidth = info.width; + info.width = vaildVal; + if (!store.CheckLockSize(true)) + { + info.width = oldWidth; + info.showWidth = oldWidth.toString(); + } + else + store.CalcDoorsInfo(); + } + else + info.showWidth = info.width.toString(); + }} /> +
+
+ store.ChangeLockStatus(info, false)} /> + + { + info.isLockHeight = true; + info.showHeight = e.currentTarget.value; + }} + onBlur={e => + { + let vaildVal = parseFloat(e.currentTarget.value); + if (!isNaN(vaildVal) && info.height !== vaildVal) + { + let oldHeight = info.height; + info.height = vaildVal; + if (!store.CheckLockSize(false)) + { + info.height = oldHeight; + info.showHeight = oldHeight.toString(); + } + else + store.CalcDoorsInfo(); + } + else + info.showHeight = info.height.toString(); + }} /> +
+ ; + } +} diff --git a/src/UI/Components/Board/DoorModal.tsx b/src/UI/Components/Board/DoorModal.tsx deleted file mode 100644 index 8505e294e..000000000 --- a/src/UI/Components/Board/DoorModal.tsx +++ /dev/null @@ -1,62 +0,0 @@ -import { inject, observer } from 'mobx-react'; -import * as React from 'react'; -import { Button } from '../../../../node_modules/@blueprintjs/core'; -import { DoorStore } from '../../Store/BoardStore'; -import { ModalState } from '../Modal/ModalsManage'; - -@inject("store") -@observer -export class DoorModal extends React.Component<{ store?: DoorStore }, {}> -{ - constructor(props) - { - super(props); - } - - render() - { - let store = this.props.store; - - return ( -
-
-
-
- -

门板设计

- -
-
-
- -
-
-
-
-
-
-
-
-
- ); - } -} diff --git a/src/UI/Components/Board/GangDrillModal.tsx b/src/UI/Components/Board/GangDrillModal.tsx index 0b73a6312..f3abd08d7 100644 --- a/src/UI/Components/Board/GangDrillModal.tsx +++ b/src/UI/Components/Board/GangDrillModal.tsx @@ -11,7 +11,7 @@ import { ModalState } from '../Modal/ModalsManage'; import { ToasterInput } from '../Toaster'; import { ItemName, SetBoardDataItem } from './BoardCommon'; import { BoardModalType } from './BoardModal'; -import { DrillType, SpacingType } from './drillInterface'; +import { DrillType, SpacingType } from '../../Store/drillInterface'; import { DrillRulesComponent } from './DrillRules'; import { UserConfig } from './UserConfig'; diff --git a/src/UI/Components/Board/UserConfig.tsx b/src/UI/Components/Board/UserConfig.tsx index b6f016ed7..a6c02dd3e 100644 --- a/src/UI/Components/Board/UserConfig.tsx +++ b/src/UI/Components/Board/UserConfig.tsx @@ -4,9 +4,9 @@ import * as React from 'react'; import { arrayLast } from '../../../Common/ArrayExt'; import { IndexedDbStore, StoreName } from '../../../IndexedDb/IndexedDbStore'; import { BoardProcessOption, LayerNailOption, TBBoardOption } from '../../Store/BoardInterface'; +import { DrillingOption } from '../../Store/drillInterface'; import { AppToaster } from '../Toaster'; -import { BoardModalProps, BoardModalType } from './BoardModal'; -import { DrillingOption } from './drillInterface'; +import { BoardModalType } from './BoardModal'; //保存的配置 export interface IConfigOption @@ -61,6 +61,13 @@ export class UserConfig extends React.Component{ }); return; } + if (!isInit && name === "默认") + { + AppToaster.show({ + message: "默认配置不能修改", + timeout: 1000 + }); + } let dbstore = await IndexedDbStore.CADStore(); let brStore = this.props.store; @@ -97,6 +104,15 @@ export class UserConfig extends React.Component{ // 删除视图中的对应项 let configs = this.state.configs; let currentName = this.state.configName; + if (currentName === "默认") + { + AppToaster.show({ + message: "默认配置不允许删除", + timeout: 1000 + }); + return; + } + configs.delete(currentName); this.setState({ configs }); @@ -158,7 +174,8 @@ export class UserConfig extends React.Component{ value={this.state.configName} onChange={e => { - this.setState({ configName: e.target.value }) + if (e.target.value.length <= 15) + this.setState({ configName: e.target.value }) }} rightElement= { diff --git a/src/UI/Components/Modal/ModalStyle/BoardModal.less b/src/UI/Components/Modal/ModalStyle/BoardModal.less index fc5411718..d955de0ea 100644 --- a/src/UI/Components/Modal/ModalStyle/BoardModal.less +++ b/src/UI/Components/Modal/ModalStyle/BoardModal.less @@ -72,7 +72,7 @@ } } //板名称输入框大小 -#modal .br-name{ +#boardModal>.board-config>.bp3-dialog-body .br-name{ width: @nameInput; } /* 排孔选项 */ diff --git a/src/UI/Components/Modal/ModalStyle/DoorModal.less b/src/UI/Components/Modal/ModalStyle/DoorModal.less new file mode 100644 index 000000000..a5ab6e0be --- /dev/null +++ b/src/UI/Components/Modal/ModalStyle/DoorModal.less @@ -0,0 +1,145 @@ +.bp3-portal{ + z-index: 30; +} +#boardModal .door{ + .boardSize .bp3-input{ + width: 4rem; + } + .flexWrap{ + width: 280px; + &> div .bp3-input{ + width: 6.5rem; + } + } + .door-pos-type{ + display: inline-block; + } + .flex-arround>div{ + text-align: center; + } + .drawerTotalDepth{ + span{ + width: 5rem; + } + } + .br-name input{ + width: 10rem; + } + .pre-canvas{ + margin-top: 4rem; + width: 350px; + height: calc(~"100% - 90px"); + max-height: 500px; + display: flex; + justify-content: space-between; + align-content: space-between; + flex-wrap: wrap; + background: #fff; + text-align: center; + color: #000; + font-weight: 500; + &>div{ + background: rgb(255,204,153); + } + .pre-item{ + outline: none; + position: relative; + &>span.opendir{ + position: absolute; + font-size: 16px; + left: 0; + right: 0; + top: 0; + bottom: 0; + margin: auto; + width: 20px; + height: 16px; + } + } + .pre-item:hover{ + background: rgb(150, 135, 121); + } + .pre-set{ + padding: 20px 10px; + outline: none; + display: flex; + justify-content: space-between; + &>div:first-child{ + margin-right: 10px; + } + } + .bp3-input-action{ + top: -4px; + right:0; + svg{ + width: 14px; + height: 14px; + } + } + .row-input{ + transform-origin: 0% 100%; + transform: translateY(-20px); + width: 80%; + left: 10%; + .bp3-input-action .bp3-checkbox{ + position: absolute; + top: 6px; + left: 32px; + } + input{ + width:100%; + } + } + .col-input{ + position: absolute; + top: 0; + text-align: left; + transform-origin: 0% 100%; + transform: rotateZ(90deg) translateY(18px); + .bp3-input-action .bp3-checkbox{ + position: absolute; + top: 6px; + } + } + .col-span{ + position: absolute; + top: calc(~'50% - 28px'); + left: 0; + transform-origin: 0% 100%; + transform: rotateZ(90deg); + + } + .row-check{ + position: absolute; + right: -20px; + top: -20px; + padding: 0; + } + .col-check{ + position: absolute; + left: 8px; + bottom: -20px; + padding: 0; + } + .bp3-html-select{ + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + margin: auto; + width: 80%; + height: 18px; + .bp3-icon{ + top: 3px; + } + } + } + + .textCenter{ + input{ + text-align: center + } + } +} + diff --git a/src/UI/Components/Modal/ModalStyle/Modal.less b/src/UI/Components/Modal/ModalStyle/Modal.less index 6216625bb..181de3f9b 100644 --- a/src/UI/Components/Modal/ModalStyle/Modal.less +++ b/src/UI/Components/Modal/ModalStyle/Modal.less @@ -126,7 +126,6 @@ width: 40%; } -// @import (less) "LightModal.less"; @import (less) "BoardModal.less"; @import (less) "ArrayModal.less"; @import (less) "DrillModal.less"; @@ -134,3 +133,5 @@ @import (less) "CommandModal.less"; @import (less) "SnapModal.less"; @import (less) "../../RightPanel/RightPanel.less"; +@import (less) "./DoorModal.less"; + diff --git a/src/UI/Components/Modal/ModalsManage.tsx b/src/UI/Components/Modal/ModalsManage.tsx index 20919d31e..eaeeac9b3 100644 --- a/src/UI/Components/Modal/ModalsManage.tsx +++ b/src/UI/Components/Modal/ModalsManage.tsx @@ -51,6 +51,7 @@ export class ModalManage // 注册事件 private RegisterEvent() { + this.m_ModalContainer.addEventListener('dragstart', e => e.preventDefault()); this.m_ModalContainer.addEventListener('keydown', e => this.OnKeyDown(e)); this.m_ModalContainer.addEventListener('focus', () => diff --git a/src/UI/Components/RightPanel/RightPanel.tsx b/src/UI/Components/RightPanel/RightPanel.tsx index 197545b9b..c46659753 100644 --- a/src/UI/Components/RightPanel/RightPanel.tsx +++ b/src/UI/Components/RightPanel/RightPanel.tsx @@ -28,11 +28,13 @@ export class RightPanel extends React.Component<{ store?: RightPanelStore }> } componentDidMount() { + const store = this.props.store; if (this.m_Container.current) this.m_Container.current.addEventListener('wheel', e => e.stopPropagation()); end(app.m_Editor.m_MaskManage, app.m_Editor.m_MaskManage.OnFocusEvent, (e: KeyboardEvent) => { - app.m_Editor.m_MaskManage.Clear(); + if (store.m_IsShow) + app.m_Editor.m_MaskManage.Clear(); }); } render() diff --git a/src/UI/Components/Toaster.tsx b/src/UI/Components/Toaster.tsx index 80e0dbe0f..4df5849c2 100644 --- a/src/UI/Components/Toaster.tsx +++ b/src/UI/Components/Toaster.tsx @@ -45,13 +45,9 @@ export class ToasterInput extends React.Component } this.showData[this.props.optKey] = e.target.value; - if ( - typeof this.props.option[this.props.optKey] === 'number' - && e.target.value !== "" - && !isNaN(parseFloat(e.target.value)) - ) + if (this.hideErrorMsg && typeof this.props.option[this.props.optKey] === 'number') { - // 该属性值为数字,不为空且有效赋值给计算属性 + //值有效,并且属性值为number this.props.option[this.props.optKey] = parseFloat(e.target.value); } else if (!this.props.uiOption) @@ -63,7 +59,8 @@ export class ToasterInput extends React.Component { //无效值不改变计算数据 } - if (this.props.onChange) + //值有效才运行change函数 + if (this.hideErrorMsg && this.props.onChange) this.props.onChange(e); } handleFocus = e => diff --git a/src/UI/Css/style.less b/src/UI/Css/style.less index beb083aa7..852549d45 100644 --- a/src/UI/Css/style.less +++ b/src/UI/Css/style.less @@ -432,15 +432,21 @@ div { display: flex; flex-wrap: wrap } -.flex-col{ - flex-direction: column; -} .ul-unstyle { list-style: none; padding: 0; } - - +.flex-arround{ + display: flex; + justify-content: space-around; +} +.flex-between{ + display: flex; + justify-content: space-between; +} +.flex-col{ + flex-direction: column; +} .half { width: 50%; } diff --git a/src/UI/Store/BoardStore.ts b/src/UI/Store/BoardStore.ts index 0dd8802c1..0f72d9c34 100644 --- a/src/UI/Store/BoardStore.ts +++ b/src/UI/Store/BoardStore.ts @@ -304,7 +304,3 @@ export class SpecialShapeStore extends BoardStore thickness: 18 } } -export class DoorStore extends BoardStore -{ - title = "门板"; -} diff --git a/src/UI/Store/DoorDrawerStore/DoorDrawerStore.ts b/src/UI/Store/DoorDrawerStore/DoorDrawerStore.ts new file mode 100644 index 000000000..97686944c --- /dev/null +++ b/src/UI/Store/DoorDrawerStore/DoorDrawerStore.ts @@ -0,0 +1,225 @@ +import { observable } from "mobx"; +import { Vector3 } from "three"; +import { IDoorAndDrawerConfigOption, IDrawerInfo, IDoorInfo } from "../DoorInterface"; +import { BoardStore } from "../BoardStore"; +import { FixedNotZero } from "../../../Common/Utils"; +import { IConfigOption } from "../../Components/Board/UserConfig"; +import { CheckoutValid, CheckObjectType } from "../../../Common/CheckoutVaildValue"; + + +export class DoorDrawerStore extends BoardStore +{ + m_Option: IDoorAndDrawerConfigOption; + totalHeight = 0; + totalWidth = 0; + totalDepth = 0; + doorWidth = 0; + doorHeight = 0; + spaceWidth = 0; + spaceHeight = 0; + preDivWidth = 0; // 预览元素尺寸 + preDivHeight = 0; + doorPosition = new Vector3(); // 第一块门板起始位置点 + previewEl: HTMLDivElement; //预览图元素 + @observable doorsInfo = []; //所有的门板信息 + InitDoorInfos() { } + protected UpdateSpace() + { + let row = this.m_Option.row; + let col = this.m_Option.col; + + this.spaceHeight = this.totalHeight; + this.spaceWidth = this.totalWidth; + //预览图尺寸 + let elSize = this.previewEl.getBoundingClientRect(); + this.preDivWidth = elSize.width; + this.preDivHeight = elSize.height; + + //处理留空 + let topOffset = this.m_Option.topOffset; + let bottomOffset = this.m_Option.bottomOffset; + this.spaceHeight -= (topOffset + bottomOffset); + this.doorPosition.add(new Vector3(0, 0, bottomOffset)); + + //处理延伸 + let topExt = this.m_Option.topExt; + let bottomExt = this.m_Option.bottomExt; + let leftExt = this.m_Option.leftExt; + let rightExt = this.m_Option.rightExt; + this.spaceWidth += (leftExt + rightExt); + this.spaceHeight += (topExt + bottomExt); + this.doorPosition.add(new Vector3(-leftExt, 0, -bottomExt)); + + //处理内偏移 + let offset = this.m_Option.offset; + this.doorPosition.add(new Vector3(0, offset, 0)); + + //处理间隙 + let topSpace = this.m_Option.topSpace; + let bottomSpace = this.m_Option.bottomSpace; + let leftSpace = this.m_Option.leftSpace; + let rightSpace = this.m_Option.rightSpace; + let centerSpace = this.m_Option.midSpace; + this.spaceWidth -= (leftSpace + rightSpace + centerSpace * (col - 1)); + this.spaceHeight -= (topSpace + bottomSpace + centerSpace * (row - 1)); + this.doorPosition.add(new Vector3(leftSpace, 0, bottomSpace)); + + //预览图间隙统一设置为4px + this.preDivHeight -= 2 * (row - 1); + this.preDivWidth -= 2 * (col - 1); + this.previewEl.style.paddingTop = this.CalcPaddingTop(topOffset) + "px"; + this.previewEl.style.paddingBottom = this.CalcPaddingTop(bottomOffset) + "px"; + + // 获取门板的长宽 + this.doorWidth = this.spaceWidth / col; + this.doorHeight = this.spaceHeight / row; + } + CalcDoorsInfo(isUpdateSpace: boolean = false) + { + if (isUpdateSpace) + this.UpdateSpace(); + + //获取已经锁定的门板信息,并将对应行列的门板信息锁定 + let lockWidthInfos: IDrawerInfo[] = []; + let lockHeightInfos: IDrawerInfo[] = []; + for (let info of this.doorsInfo) + { + if (info.col === 0) + { + if (info.isLockHeight) + { + lockHeightInfos.push(info); + } + for (let inf of this.doorsInfo) + { + if (inf !== info && info.row === inf.row) + { + inf.isLockHeight = info.isLockHeight; + inf.height = info.height; + } + } + } + if (info.row === 0) + { + if (info.isLockWidth) + lockWidthInfos.push(info); + for (let inf of this.doorsInfo) + { + if (inf !== info && info.col === inf.col) + { + inf.isLockWidth = info.isLockWidth; + inf.width = info.width; + } + } + } + } + + let row = this.m_Option.row; + let col = this.m_Option.col; + + // 锁定尺寸后剩余空间和已经锁定的总尺寸 + let retWidth = 0; + let setWidth = 0; + let retHeight = 0; + let setHeight = 0; + for (let info of lockWidthInfos) + { + setWidth += info.width; + } + for (let info of lockHeightInfos) + { + setHeight += info.height; + } + + retWidth = this.spaceWidth - setWidth; + let retDoorWidth = retWidth / (col - lockWidthInfos.length); + + // 用于计算预览图UI的参考尺寸 + let refWidth = lockWidthInfos.length === col ? setWidth : this.spaceWidth; + retHeight = this.spaceHeight - setHeight; + let refHeight = lockHeightInfos.length === row ? setHeight : this.spaceHeight; + let retDoorHeight = retHeight / (row - lockHeightInfos.length); + + //修改剩余未锁定的门板信息 + for (let info of this.doorsInfo) + { + if (!info.isLockWidth) + { + info.width = retDoorWidth; + info.showWidth = FixedNotZero(retDoorWidth); + } + if (!info.isLockHeight) + { + info.height = retDoorHeight; + info.showHeight = FixedNotZero(retDoorHeight); + } + info.divWidth = this.DoorSizeConvertDivSize(info.width, true, refWidth); + info.divHeight = this.DoorSizeConvertDivSize(info.height, false, refHeight); + } + } + private DoorSizeConvertDivSize(size: number, isWidth: boolean, refSize?: number, ) + { + let divSize = isWidth ? this.preDivWidth : this.preDivHeight; + if (!isWidth) + { + let paddingTop = parseFloat(this.previewEl.style.paddingTop); + let paddingBottom = parseFloat(this.previewEl.style.paddingBottom); + if (paddingTop) + divSize -= paddingTop; + if (paddingBottom) + divSize -= paddingBottom; + + } + let spaceSize = isWidth ? this.spaceWidth : this.spaceHeight; + if (refSize) + spaceSize = refSize; + return divSize / spaceSize * size; + } + /** + * + * 检查锁定是否有效 + */ + CheckLockSize(isWidth: boolean) + { + let size = 0; + let refSize = isWidth ? this.spaceWidth : this.spaceHeight; + for (let info of this.doorsInfo) + { + let refRet = isWidth ? + (info.row === 0 && info.isLockWidth) : (info.col === 0 && info.isLockHeight) + if (refRet) + size += isWidth ? info.width : info.height; + } + return size <= refSize; + } + + /** + * 更改锁定状态 + */ + ChangeLockStatus(info: IDrawerInfo, isWidth: boolean) + { + if (isWidth) + info.isLockWidth = !info.isLockWidth; + else + info.isLockHeight = !info.isLockHeight; + this.CalcDoorsInfo(); + } + private CalcPaddingTop(size: number) + { + return this.preDivHeight / this.totalHeight * size; + } + UpdateOption(cof: IConfigOption) + { + super.UpdateOption(cof); + if (this.m_Option.isAuto) + { + this.m_Option.depth = this.totalDepth; + this.m_UiOption.depth = this.totalDepth.toString(); + } + this.InitDoorInfos(); + } + HasInvailValue() + { + return CheckoutValid.HasInvailValue(this.UIOption, CheckObjectType.Do) + } +} diff --git a/src/UI/Store/DoorDrawerStore/DoorStore.ts b/src/UI/Store/DoorDrawerStore/DoorStore.ts new file mode 100644 index 000000000..a5729a58a --- /dev/null +++ b/src/UI/Store/DoorDrawerStore/DoorStore.ts @@ -0,0 +1,141 @@ +import { DoorDrawerStore } from "./DoorDrawerStore"; +import { HandleHorPos, HandleVePos, DoorPosType, IDoorConfigOption, IDoorInfo, DoorOpenDir } from "../DoorInterface"; +import { observable } from "mobx"; +import { FixedNotZero } from "../../../Common/Utils"; +import { Vector3 } from "three"; + +export const openDirTitle = {}; //门板开门类型对应 +openDirTitle[DoorOpenDir.Left] = "左"; +openDirTitle[DoorOpenDir.Right] = "右"; +openDirTitle[DoorOpenDir.Top] = "上"; +openDirTitle[DoorOpenDir.Bottom] = "下"; +openDirTitle[DoorOpenDir.None] = "无"; + +export class DoorStore extends DoorDrawerStore +{ + title = "门板"; + @observable m_Option: IDoorConfigOption = { + col: 1, + row: 1, + isAllSelect: true, + topOffset: 0, + bottomOffset: 0, + doorPosType: DoorPosType.Out, + offset: 0, + topExt: 18, + bottomExt: 18, + leftExt: 18, + rightExt: 18, + topSpace: 2, + bottomSpace: 2, + leftSpace: 2, + rightSpace: 2, + midSpace: 2, + thickness: 18, + depth: 0, + isAuto: true, + boardName: "", + doorThickness: 18, + topBrSeal: 1, + bottomBrSeal: 1, + leftBrSeal: 1, + rightBrSeal: 1, + topDoorSeal: 1, + bottomDoorSeal: 1, + leftDoorSeal: 1, + rightDoorSeal: 1, + handleAngle: 0, + handleHorPos: HandleHorPos.Left, + horSpacing: 10, + handleVePos: HandleVePos.Top, + veSpacing: 10, + hingeCount: 0, + hindeTopDist: 0, + hindeBottomDist: 0, + } + @observable doorsInfo: IDoorInfo[] = []; + InitDoorInfos() + { + this.UpdateSpace(); + let row = this.m_Option.row; + let col = this.m_Option.col; + let rectWidth = this.preDivWidth / col; + let paddingTop = parseFloat(this.previewEl.style.paddingTop); + let paddingBottom = parseFloat(this.previewEl.style.paddingBottom); + let preHeight = this.preDivHeight; + if (paddingTop) + preHeight -= paddingTop; + if (paddingBottom) + preHeight -= paddingBottom; + let rectHeight = preHeight / row; + this.doorsInfo.length = 0; + for (let i = 0; i < row; i++) + { + for (let j = 0; j < col; j++) + { + this.doorsInfo.push({ + row: i, + col: j, + openDir: (j & 1) === 1 || j === col - 1 ? DoorOpenDir.Right : DoorOpenDir.Left, + divWidth: rectWidth, + divHeight: rectHeight, + showWidth: FixedNotZero(this.doorWidth), + showHeight: FixedNotZero(this.doorHeight), + width: this.doorWidth, + height: this.doorHeight, + isLockWidth: false, + isLockHeight: false, + isDrawLayer: false, + isDrawVer: (j & 1) === 1 && j !== col - 1 + }) + } + } + } + UpdateSpace() + { + super.UpdateSpace(); + //门板起始距离需偏移一个门板厚度 + let doorThickness = this.m_Option.doorThickness; + this.doorPosition.add(new Vector3(0, -doorThickness, 0)); + } + /** + * 改变开门类型 + */ + ChangeOpenDir(info: IDoorInfo) + { + for (let inf of this.doorsInfo) + { + if (inf === info) + { + if (info.openDir === DoorOpenDir.Right) + inf.isDrawVer = true; + else if (info.openDir === DoorOpenDir.Bottom) + inf.isDrawLayer = true; + continue; + }; + let isUpdateOpenDir = false; + + if (info.openDir === DoorOpenDir.Left || info.openDir === DoorOpenDir.Right) + { + isUpdateOpenDir = inf.col === info.col; + if (info.openDir === DoorOpenDir.Left) + { + if (inf.col === info.col - 1) + inf.isDrawVer = true; + } + } + else if (info.openDir === DoorOpenDir.Top || info.openDir === DoorOpenDir.Bottom) + { + isUpdateOpenDir = inf.row === info.row; + + if (info.openDir === DoorOpenDir.Top) + { + if (inf.row === info.row - 1) + inf.isDrawLayer = true; + } + + } + if (isUpdateOpenDir) inf.openDir = info.openDir; + } + } +} diff --git a/src/UI/Store/DoorDrawerStore/DrawerStore.ts b/src/UI/Store/DoorDrawerStore/DrawerStore.ts new file mode 100644 index 000000000..6422060a5 --- /dev/null +++ b/src/UI/Store/DoorDrawerStore/DrawerStore.ts @@ -0,0 +1,73 @@ +import { observable } from "mobx"; +import { IDrawerInfo, IDrawerConfigOption, DoorPosType, HandleHorPos, HandleVePos } from "../DoorInterface"; +import { DoorDrawerStore } from "./DoorDrawerStore"; +import { FixedNotZero } from "../../../Common/Utils"; +export class DrawerStore extends DoorDrawerStore +{ + title = "抽屉"; + @observable m_Option: IDrawerConfigOption = { + col: 1, + row: 1, + isAllSelect: true, + topOffset: 0, + bottomOffset: 0, + doorPosType: DoorPosType.Out, + offset: 0, + topExt: 18, + bottomExt: 18, + leftExt: 18, + rightExt: 18, + topSpace: 2, + bottomSpace: 2, + leftSpace: 2, + rightSpace: 2, + midSpace: 2, + thickness: 18, + depth: 0, + isAuto: true, + boardName: "", + handleAngle: 0, + handleHorPos: HandleHorPos.Left, + horSpacing: 10, + handleVePos: HandleVePos.Top, + veSpacing: 10, + drawerTotalDepth: 0, + trackDepth: 0, + isAutoSelectTrack: true, + } + @observable doorsInfo: IDrawerInfo[] = []; + InitDoorInfos() + { + this.UpdateSpace(); + let row = this.m_Option.row; + let col = this.m_Option.col; + let rectWidth = this.preDivWidth / col; + let paddingTop = parseFloat(this.previewEl.style.paddingTop); + let paddingBottom = parseFloat(this.previewEl.style.paddingBottom); + let preHeight = this.preDivHeight; + if (paddingTop) + preHeight -= paddingTop; + if (paddingBottom) + preHeight -= paddingBottom; + let rectHeight = preHeight / row; + this.doorsInfo.length = 0; + for (let i = 0; i < row; i++) + { + for (let j = 0; j < col; j++) + { + this.doorsInfo.push({ + row: i, + col: j, + divWidth: rectWidth, + divHeight: rectHeight, + showWidth: FixedNotZero(this.doorWidth, 1), + showHeight: FixedNotZero(this.doorHeight, 1), + width: this.doorWidth, + height: this.doorHeight, + isLockWidth: false, + isLockHeight: false, + }) + } + } + } +} diff --git a/src/UI/Store/DoorInterface.ts b/src/UI/Store/DoorInterface.ts new file mode 100644 index 000000000..dc7316c67 --- /dev/null +++ b/src/UI/Store/DoorInterface.ts @@ -0,0 +1,109 @@ +export interface IDoorAndDrawerConfigOption +{ + col: number; + row: number; + isAllSelect: boolean; //是否行列全选 + topOffset: number; //上留空 + bottomOffset: number; //下留空 + doorPosType: DoorPosType; + offset: number; //内偏移 + topExt: number; + bottomExt: number; + leftExt: number; + rightExt: number; + topSpace: number; //间隙 + bottomSpace: number; + leftSpace: number; + rightSpace: number; + midSpace: number; + thickness: number; //立板厚度 + depth: number; //立板深度 + isAuto: boolean; //智能识别 + boardName: string; + handleAngle: number; //拉手 + handleHorPos: HandleHorPos; //水平位置距离 + horSpacing: number; + handleVePos: HandleVePos; // 垂直位置距离 + veSpacing: number; +} + +/** + * 门板数据接口 + */ +export interface IDoorConfigOption extends IDoorAndDrawerConfigOption +{ + doorThickness: number; //门板厚度 + topBrSeal: number; //层板封边 + bottomBrSeal: number; + leftBrSeal: number; + rightBrSeal: number; + topDoorSeal: number; //门板封边 + bottomDoorSeal: number; + leftDoorSeal: number; + rightDoorSeal: number; + hingeCount: number; //铰链 + hindeTopDist: number; + hindeBottomDist: number +} + +/** + * 抽屉数据接口 + */ +export interface IDrawerConfigOption extends IDoorAndDrawerConfigOption +{ + drawerTotalDepth: number; //抽屉总深 + trackDepth: number; //轨道深度 + isAutoSelectTrack: boolean; +} + +//门板位置类型 +export enum DoorPosType +{ + Out = 0, //外盖 + In = 1, +} + +export enum HandleHorPos +{ + Left = 0, + Right = 1, + Mid = 2, +} +export enum HandleVePos +{ + Top = 0, + Bottom = 1, + Mid = 2, +} +//门板开门类型 +export enum DoorOpenDir +{ + Left = "lf", + Right = "rt", + Top = "tp", + Bottom = "bm", + None = "none", +} + +//抽屉门板信息 +export interface IDrawerInfo +{ + row: number, + col: number, + divWidth: number, //预览UI尺寸 + divHeight: number, + showWidth: string, //UI展示数据 + showHeight: string, + width: number, //门板计算尺寸 + height: number, + isLockWidth: boolean, + isLockHeight: boolean, +} + +export interface IDoorInfo extends IDrawerInfo +{ + openDir: DoorOpenDir, + + isDrawLayer: boolean; + isDrawVer: boolean; +} diff --git a/src/UI/Store/DrillStore.ts b/src/UI/Store/DrillStore.ts index 861e93c22..56859e22a 100644 --- a/src/UI/Store/DrillStore.ts +++ b/src/UI/Store/DrillStore.ts @@ -1,6 +1,6 @@ import { observable, toJS } from "mobx"; import { CheckObjectType, CheckoutValid } from "../../Common/CheckoutVaildValue"; -import { DrillingOption, DrillType, SpacingType } from "../Components/Board/drillInterface"; +import { DrillingOption, DrillType, SpacingType } from "./drillInterface"; import { IConfigOption } from "../Components/Board/UserConfig"; import { BoardStore } from "./BoardStore"; import { DataAdapter } from "../../Common/DataAdapter"; diff --git a/src/UI/Components/Board/drillInterface.ts b/src/UI/Store/drillInterface.ts similarity index 100% rename from src/UI/Components/Board/drillInterface.ts rename to src/UI/Store/drillInterface.ts