!228 门板部分功能和抽屉UI

Merge pull request !228 from ZoeLeeFZ/door5
pull/228/MERGE
ChenX 6 years ago
parent d8495566cb
commit 1e9b523685

@ -1,25 +0,0 @@
import { commandMachine } from "../../Editor/CommandMachine";
import { CommandState } from "../../Editor/CommandState";
export class DrawBoardServer
{
static m_DrawMap: Map<string, Function> = 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);
}
}
}

@ -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';

@ -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);
}
}
}
}
}

@ -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:实现绘制抽屉
}
}
}

@ -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
{

@ -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)
}
}
}

@ -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++)

@ -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;
}
}

@ -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} />
<BoardModel />
<BoardDirectionIcon />
<SetBoardDataItem
type={CheckObjectType.BR}
title="右延伸"

@ -5,7 +5,7 @@ import { CheckObjectType } from '../../../Common/CheckoutVaildValue';
import { BoardType } from '../../../DatabaseServices/Board';
import { BoardConfigOption, BoardOption, BrRelativePos, TBBoardOption } from '../../Store/BoardInterface';
import { ToasterInput } from '../Toaster';
import { DrillingOption } from './drillInterface';
import { DrillingOption } from '../../Store/drillInterface';
type OptionType = BoardOption | DrillingOption;
@ -18,8 +18,9 @@ export interface ISetItemOption
uiOption?: Object;
isDisabled?: boolean;
placeHolder?: string;
onChange?: (e)=>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<ISetItemOption, {}>
{
const props = this.props;
return (
<div className={"br-set " + (props.inline ? "inline" : "")}>
<div className={props.className + " br-set " + (props.inline ? "inline" : "")}>
<span>
{props.title}:
</span>
@ -75,65 +77,70 @@ export const SetBoardDataBlock = observer(
option={props.option}
uiOption={props.uiOption}
title={v}
onChange={() =>
{
if (props.onChange)
props.onChange();
}}
/>
)
}
</div>
);
export const TBBoardDataBlock =
observer(
(props: TBProps) =>
{
return (
<div className="pt-card pt-elevation-0 tb-br">
<Checkbox
style={
{
fontSize: "1.4rem",
fontWeight: 600
}
}
checked={props.option.isDraw}
label={props.istop ? "顶板" : "底板"}
onChange={() => props.option.isDraw = !props.option.isDraw}
/>
<RadioGroup
className="flex"
onChange={e => props.option.isWrapSide = e.currentTarget.value === "1"}
selectedValue={props.option.isWrapSide ? "1" : "0"}
>
<Radio className="widthHalf" label={props.istop ? "侧包顶" : "侧包底"} value="0" />
<Radio className="widthHalf" label={props.istop ? "顶包侧" : "底包侧"} value="1" />
</RadioGroup>
<div className="flexWrap">
export const TBBoardDataBlock = observer(
(props: TBProps) =>
{
return (
<div className="pt-card pt-elevation-0 tb-br">
<Checkbox
style={
{
props.pars.map(([k, v]) =>
{
if (k === "offset" && !props.istop)
v = "下留"
return (
<SetBoardDataItem
type={CheckObjectType.BR}
title={v}
optKey={k}
key={k}
option={props.option}
uiOption={props.uiOption}
isDisabled={
((k === "rightExt" || k === "leftExt") && !props.option.isWrapSide) ||
(k === "offset" && props.option.isWrapSide)
} />
)
})
fontSize: "1.4rem",
fontWeight: 600
}
</div>
}
checked={props.option.isDraw}
label={props.istop ? "顶板" : "底板"}
onChange={() => props.option.isDraw = !props.option.isDraw}
/>
<RadioGroup
className="flex"
onChange={e => props.option.isWrapSide = e.currentTarget.value === "1"}
selectedValue={props.option.isWrapSide ? "1" : "0"}
>
<Radio className="widthHalf" label={props.istop ? "侧包顶" : "侧包底"} value="0" />
<Radio className="widthHalf" label={props.istop ? "顶包侧" : "底包侧"} value="1" />
</RadioGroup>
<div className="flexWrap">
{
props.pars.map(([k, v]) =>
{
if (k === "offset" && !props.istop)
v = "下留"
return (
<SetBoardDataItem
type={CheckObjectType.BR}
title={v}
optKey={k}
key={k}
option={props.option}
uiOption={props.uiOption}
isDisabled={
((k === "rightExt" || k === "leftExt") && !props.option.isWrapSide) ||
(k === "offset" && props.option.isWrapSide)
} />
)
})
}
</div>
)
});
</div>
)
}
);
export const BoardModel = () =>
/* 显示板件的方向(封边使用) */
export const BoardDirectionIcon = () =>
<label className="boardModel">
<span className="arrow arrowtop"></span>
<span className="line"></span>
@ -250,3 +257,71 @@ export const BoardTypeComponent = observer((data: { opt?: BoardConfigOption, cla
</label>
)
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<I5InputComponent, {}>
{
render()
{
return (
<div className="boardSize center textCenter">
<ToasterInput
type={this.props.type}
optKey={this.props.upKey}
option={this.props.option}
uiOption={this.props.uiOption}
onChange={this.props.onChange}
/>
<div>
<ToasterInput
type={this.props.type}
optKey={this.props.leftKey}
option={this.props.option}
uiOption={this.props.uiOption}
onChange={this.props.onChange}
/>
{
this.props.showDirectionIcon && <BoardDirectionIcon />
}
{
this.props.hasCenter && <ToasterInput
type={this.props.type}
optKey={this.props.centerKey}
option={this.props.option}
uiOption={this.props.uiOption}
onChange={this.props.onChange}
/>
}
<ToasterInput
type={this.props.type}
optKey={this.props.rightKey}
option={this.props.option}
uiOption={this.props.uiOption}
onChange={this.props.onChange}
/>
</div>
<ToasterInput
type={this.props.type}
optKey={this.props.downKey}
option={this.props.option}
uiOption={this.props.uiOption}
onChange={this.props.onChange}
/>
</div>
)
}
}

@ -29,6 +29,7 @@ export enum BoardModalType
Skt = "skt",//收口条
Dr = "dr",//排钻
Zx = "zx", //造型
Mb = "mb", // 门板
}
export interface BoardModalProps
{

@ -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<BoardProcessProps, {}>{
<h6 className={"edge-sealing " + Classes.HEADING}>
{
isShowHighEditor ? (
<EdgeSealingComponent br={this.props.br} />
)
: null
isShowHighEditor && <EdgeSealingComponent br={this.props.br} />
}
</h6>
<div className="boardSize center" style={{ display: isShowHighEditor ? "none" : "block" }}>
<ToasterInput
type={CheckObjectType.BR}
optKey="sealedUp"
option={this.props.opt}
/>
<div>
<ToasterInput
type={CheckObjectType.BR}
optKey="sealedLeft"
option={this.props.opt}
/>
<BoardModel />
<ToasterInput
type={CheckObjectType.BR}
optKey="sealedRight"
option={this.props.opt}
/>
</div>
<ToasterInput
{
!isShowHighEditor && <Input5Or4Component
type={CheckObjectType.BR}
optKey="sealedDown"
showDirectionIcon={true}
hasCenter={false}
optKey=""
upKey="sealedUp"
downKey="sealedDown"
leftKey="sealedLeft"
rightKey="sealedRight"
option={this.props.opt}
/>
</div>
}
</div>
)
}

@ -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 (
<>
<div>
<SetBoardDataItem
type={CheckObjectType.Do}
optKey="col"
option={store.m_Option}
uiOption={this.uiOption}
title="列"
inline={true}
onChange={() =>
{
if (store.m_Option.col > 20)
{
store.m_Option.col = 20;
store.UIOption.col = "20";
}
store.InitDoorInfos();
}}
/>
<SetBoardDataItem
type={CheckObjectType.Do}
optKey="row"
option={store.m_Option}
uiOption={this.uiOption}
title="行"
inline={true}
onChange={() =>
{
if (store.m_Option.row > 20)
{
store.m_Option.row = 20;
store.UIOption.row = "20";
}
store.InitDoorInfos();
}}
/>
<Checkbox
inline={true}
checked={store.m_Option.isAllSelect}
label="行列全选"
/>
</div>
<Divider />
<SetBoardDataBlock
type={CheckObjectType.Do}
className="flexWrap"
pars={[["topOffset", "上留空"], ["bottomOffset", "下留空"]]}
option={store.m_Option}
uiOption={this.uiOption}
onChange={() =>
{
if (store.m_Option.topOffset + store.m_Option.bottomOffset < store.totalHeight)
store.CalcDoorsInfo(true);
}}
/>
<Divider />
<div>
<div>
<RadioGroup
className="door-pos-type"
inline={true}
selectedValue={store.m_Option.doorPosType}
onChange={this.handleChangeDoorPosType}
>
<Radio label="外盖" value={DoorPosType.Out} />
<Radio label="内嵌" value={DoorPosType.In} />
</RadioGroup>
<ToasterInput
type={CheckObjectType.Do}
optKey="offset"
option={store.m_Option}
uiOption={this.uiOption}
inline={true}
/>
</div>
<div className="flex-arround">
<div>
<H6></H6>
<Input5Or4Component
type={CheckObjectType.Do}
showDirectionIcon={false}
hasCenter={false}
optKey=""
upKey="topExt"
downKey="bottomExt"
leftKey="leftExt"
rightKey="rightExt"
option={store.m_Option}
uiOption={this.uiOption}
onChange={() => store.CalcDoorsInfo(true)}
/>
</div>
<div>
<H6></H6>
<Input5Or4Component
type={CheckObjectType.Do}
showDirectionIcon={false}
hasCenter={true}
optKey=""
upKey="topSpace"
downKey="bottomSpace"
leftKey="leftSpace"
rightKey="rightSpace"
centerKey="midSpace"
option={store.m_Option}
uiOption={this.uiOption}
onChange={() => store.CalcDoorsInfo(true)}
/>
</div>
</div>
</div>
<Divider />
<div>
<SetBoardDataItem
type={CheckObjectType.Do}
optKey="thickness"
option={store.m_Option}
uiOption={this.uiOption}
title="立板厚"
inline={true}
/>
<SetBoardDataItem
type={CheckObjectType.Do}
optKey="depth"
option={store.m_Option}
uiOption={this.uiOption}
title={this.isDoor ? "立板深" : "抽屉深"}
inline={true}
isDisabled={store.m_Option.isAuto}
/>
<Checkbox
inline={true}
checked={store.m_Option.isAuto}
label="智能识别"
onChange={() =>
{
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 && <SetBoardDataItem
className="drawerTotalDepth"
type={CheckObjectType.Do}
optKey="drawerTotalDepth"
option={store.m_Option}
uiOption={this.uiOption}
title="抽屉总深"
/>
}
</div>
<Divider />
<div className={this.isDoor && "flexWrap"}>
<SetBoardDataItem
className={!this.isDoor && "br-name"}
type={CheckObjectType.Do}
optKey="boardName"
option={store.m_Option}
title="柜名"
placeHolder="输入柜名"
/>
{
this.isDoor && <SetBoardDataItem
type={CheckObjectType.Do}
optKey="doorThickness"
option={store.m_Option}
uiOption={this.uiOption}
title="门板厚"
/>
}
</div>
<Divider />
{
this.isDoor && <div className="flex-arround">
<div>
<H6></H6>
<Input5Or4Component
type={CheckObjectType.Do}
showDirectionIcon={false}
hasCenter={false}
optKey=""
upKey="topBrSeal"
downKey="bottomBrSeal"
leftKey="leftBrSeal"
rightKey="rightBrSeal"
option={store.m_Option}
uiOption={this.uiOption}
/>
</div>
<div>
<H6></H6>
<Input5Or4Component
type={CheckObjectType.Do}
showDirectionIcon={false}
hasCenter={false}
optKey=""
upKey="topDoorSeal"
downKey="bottomDoorSeal"
leftKey="leftDoorSeal"
rightKey="rightDoorSeal"
option={store.m_Option}
uiOption={this.uiOption}
/>
</div>
</div>
}
<H5></H5>
<div>
<SetBoardDataItem
type={CheckObjectType.Do}
optKey="handleAngle"
option={store.m_Option}
uiOption={this.uiOption}
title="旋转角"
/>
<div>
<RadioGroup
className="door-pos-type"
inline={true}
selectedValue={store.m_Option.handleHorPos}
onChange={e =>
{
store.m_Option.handleHorPos = parseFloat(e.currentTarget.value) as HandleHorPos;
}}
>
<Radio label="左距" value={HandleHorPos.Left} />
<Radio label="右距" value={HandleHorPos.Right} />
<Radio label="居中" value={HandleHorPos.Mid} />
</RadioGroup>
<ToasterInput
type={CheckObjectType.Do}
optKey="horSpacing"
option={store.m_Option}
uiOption={this.uiOption}
inline={true}
/>
</div>
<div>
<RadioGroup
className="door-pos-type"
inline={true}
selectedValue={store.m_Option.handleVePos}
onChange={e =>
{
store.m_Option.handleVePos = parseFloat(e.currentTarget.value) as HandleVePos;
}}
>
<Radio label="上距" value={HandleVePos.Top} />
<Radio label="下距" value={HandleVePos.Bottom} />
<Radio label="居中" value={HandleVePos.Mid} />
</RadioGroup>
<ToasterInput
type={CheckObjectType.Do}
optKey="horSpacing"
option={store.m_Option}
uiOption={this.uiOption}
inline={true}
/>
</div>
</div>
{
this.isDoor ? <>
<H5></H5>
<SetBoardDataBlock
type={CheckObjectType.Do}
className="flexWrap"
pars={[["hindeTopDist", "上距"], ["hindeBottomDist", "下距"], ["hingeCount", "铰链数"]]}
option={store.m_Option}
uiOption={this.uiOption}
/>
</> : <>
<H5></H5>
<div>
<SetBoardDataItem
type={CheckObjectType.Do}
optKey="trackDepth"
option={store.m_Option}
uiOption={this.uiOption}
title="轨道深"
inline={true}
/>
<Checkbox
inline={true}
checked={store.m_Option["isAutoSelectTrack"]}
label="智能识别"
onChange={() => store.m_Option["isAutoSelectTrack"] = !store.m_Option["isAutoSelectTrack"]}
/>
</div>
</>
}
</>
)
}
}

@ -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 (
<div
className={Classes.DIALOG_CONTAINER}
id="boardModal"
>
<div className={Classes.DIALOG}>
<div
className={Classes.DIALOG_HEADER}
data-id="dragArea"
>
<Icon icon="remove-column-left" iconSize={18} />
<h4 className="bp3-heading">{store.title}</h4>
<Button
aria-label="Close"
minimal
icon="cross"
className={Classes.DIALOG_CLOSE_BUTTON}
onClick={() => store.OnOk(ModalState.Cancel)}
/>
</div>
<div
className={Classes.DIALOG_BODY + " door"}
>
<div className="flex">
<div className={Classes.CARD}>
<DoorConfigModal store={this.props.store} />
</div>
<div className={Classes.CARD}>
<DoorPreviewComponent store={this.props.store} />
</div>
<div className={Classes.CARD}>
<H5></H5>
<H5></H5>
<H5></H5>
</div>
</div>
</div>
<div className={Classes.DIALOG_FOOTER} >
<UserConfig store={store} type={BoardModalType.Mb} />
<div className={Classes.DIALOG_FOOTER_ACTIONS}>
<Button
className="LeftRightBtn bp3-intent-danger"
text="选择模板"
/>
<Button
className="LeftRightBtn bp3-intent-success"
text="确定"
onClick={() =>
{
if (store.HasInvailValue())
AppToaster.show({ message: "存在无效数值,请修正", timeout: 1000 });
else
store.OnOk(ModalState.Ok);
}
}
/>
<Button
className="LeftRightBtn bp3-intent-danger" text="取消"
onClick={() => store.OnOk(ModalState.Cancel)}
/>
</div>
</div>
</div>
</div>
);
}
}

@ -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 (
<>
<div className="flex-between">
<span>:{store.totalWidth}mm</span>
<span>:{store.totalDepth}mm</span>
<span>:{store.totalHeight}mm</span>
</div>
<div
ref={el =>
{
if (el)
store.previewEl = el;
}}
className="pre-canvas">
{
store.doorsInfo.map(info =>
{
return (
<DoorPreviewItem
store={store}
info={info}
doorCom={
(info.divWidth <= refSize || info.divHeight <= refSize) ?
DoorPreviewSmItem :
DoorPreviewLgItem
}
/>
)
})
}
</div>
</>
)
}
}

@ -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<IDoorPreviewItemProps, {}>
{
render()
{
const { store, info } = this.props;
const isDoor = store instanceof DoorStore;
return (
<div
className="pre-item textCenter"
onDoubleClick={this.props.onDbClick}
style={getCalcStyles(info, store)}>
{
info.row === 0 &&
<InputGroup
value={info.showWidth}
className="row-input"
rightElement={
<>
<Button
icon={info.isLockWidth ? "lock" : "unlock"}
minimal
onClick={() => store.ChangeLockStatus(info, true)}
/>
{
isDoor && info.col !== store.m_Option.col - 1 &&
<Checkbox
checked={info.isDrawVer}
onChange={() =>
{
info.isDrawVer = !info.isDrawVer
}}
/>
}
</>
}
onChange={e =>
{
info.isLockWidth = true;
let val = e.currentTarget.value;
info.showWidth = val;
}}
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 = FixedNotZero(info.width);
}}
/>
}
{
info.col === 0 &&
<InputGroup
className="col-input"
style={{
width: info.divHeight * 0.8,
}}
value={info.showHeight}
rightElement={
<>
<Button
icon={info.isLockHeight ? "lock" : "unlock"}
minimal
onClick={() => store.ChangeLockStatus(info, false)}
/>
{
isDoor && info.row !== store.m_Option.row - 1 &&
<Checkbox
checked={info.isDrawLayer}
style={{
left: 0.2 * info.divHeight
}}
onChange={() =>
{
info.isDrawLayer = !info.isDrawLayer
}}
/>
}
</>
}
onChange={e =>
{
info.isLockHeight = true;
let val = e.currentTarget.value;
info.showHeight = val;
}}
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 = FixedNotZero(info.height);
}}
/>
}
{
isDoor && <HTMLSelect
value={info.openDir}
options={[
{
label: "左开门",
value: DoorOpenDir.Left
},
{
label: "右开门",
value: DoorOpenDir.Right
},
{
label: "上开门",
value: DoorOpenDir.Top
},
{
label: "下开门",
value: DoorOpenDir.Bottom
},
{
label: "无类型",
value: DoorOpenDir.None
},
]}
onChange={e =>
{
info.openDir = e.currentTarget.value as DoorOpenDir;
(store as DoorStore).ChangeOpenDir(info);
}}
/>
}
</div>
)
}
}
//预览图门板比较小时渲染
@observer
export class DoorPreviewSmItem extends React.Component<IDoorPreviewItemProps, {}>{
render()
{
const { info, store } = this.props;
const isDoor = store instanceof DoorStore;
return (
<div
onDoubleClick={this.props.onDbClick}
className="pre-item"
style={{
width: info.divWidth + "px",
height: info.divHeight + "px",
}}
tabIndex={-1}
>
{
isDoor && <span className="opendir">
{openDirTitle[info.openDir]}
</span>
}
{
info.row === 0 && <span>
{info.showWidth}
</span>
}
{
info.col === 0 && <span className="col-span">
{info.showHeight}
</span>
}
<div
onMouseDown={e => e.stopPropagation()}
onClick={e => e.stopPropagation()}
onDoubleClick={e => e.stopPropagation()}
>
{
isDoor && (info.row === 0 && info.col !== store.m_Option.col - 1) &&
<Checkbox
tabIndex={-1}
className="row-check"
checked={info.isDrawVer}
onChange={() =>
{
info.isDrawVer = !info.isDrawVer;
}}
/>
}
{
isDoor && (info.col === 0 && info.row !== store.m_Option.row - 1) &&
<Checkbox
className="col-check"
checked={info.isDrawLayer}
onClick={e =>
{
e.stopPropagation();
}}
onChange={() =>
{
info.isDrawLayer = !info.isDrawLayer;
}}
/>
}
</div>
</div>
)
}
}
@observer
export class DoorPreviewItem extends React.Component<IDoorPreviewItemProps, {}>{
@observable isOpen = false;
render()
{
const { info, store } = this.props;
const isDoor = store instanceof DoorStore;
return (
<div style={getCalcStyles(info, store)}>
<Popover
usePortal={false}
isOpen={this.isOpen}
hasBackdrop
onOpened={e =>
(e.parentElement.firstElementChild as HTMLDivElement).onclick = () =>
{
this.isOpen = false;
}
}
modifiers={{
flip: { enabled: true },
keepTogether: { enabled: true },
preventOverflow: { enabled: true, boundariesElement: "scrollParent" }
}}
content={
<div
className="pre-set"
tabIndex={-1}
>
{this.RenderRadiusOption(isDoor, info, store)}
<div className="textCenter">
{this.RenderInputAndLock(info, store, isDoor)}
</div>
</div>
}
target={
<this.props.doorCom {...this.props} onDbClick={() => this.isOpen = true} />
}
>
</Popover>
</div>
)
}
private RenderRadiusOption(isDoor: boolean, info: IDoorInfo, store: DoorDrawerStore)
{
return (isDoor && <RadioGroup
selectedValue={info.openDir}
onChange={(e) =>
{
info.openDir = e.currentTarget.value as DoorOpenDir;
(store as DoorStore).ChangeOpenDir(info);
}}
>
<Radio label="左开门" value={DoorOpenDir.Left} />
<Radio label="右开门" value={DoorOpenDir.Right} />
<Radio label="上开门" value={DoorOpenDir.Top} />
<Radio label="下开门" value={DoorOpenDir.Bottom} />
<Radio label="无类型" value={DoorOpenDir.None} />
</RadioGroup>)
}
private RenderInputAndLock(info: IDoorInfo, store: DoorDrawerStore, isDoor: boolean): React.ReactNode
{
return (info.row === 0 || info.col === 0 || !isDoor) &&
<>
<div>
<Checkbox inline={true} label="锁定宽度" checked={info.isLockWidth} onChange={() => store.ChangeLockStatus(info, true)} />
<input
style={{ width: "5.5rem" }}
className={Classes.INPUT}
value={info.showWidth}
onChange={e =>
{
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();
}} />
</div>
<div>
<Checkbox inline={true} label="锁定高度" checked={info.isLockHeight} onChange={() => store.ChangeLockStatus(info, false)} />
<input
style={{ width: "5.5rem" }}
className={Classes.INPUT}
value={info.showHeight}
onChange={e =>
{
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();
}} />
</div>
</>;
}
}

@ -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 (
<div>
<div
className="bp3-dialog-container"
id="boardModal"
>
<div className="bp3-dialog">
<div
className="bp3-dialog-header"
data-id="dragArea"
>
<span className="bp3-icon-large bp3-icon-inbox"></span>
<h4 className="bp3-heading"></h4>
<button
aria-label="Close" className="bp3-dialog-close-button bp3-icon-small-cross"
onClick={() => store.OnOk(ModalState.Cancel)}
></button>
</div>
<div
className="bp3-dialog-body"
>
<div className="bp3-card">
</div>
</div>
<div className="bp3-dialog-footer">
<div className="bp3-dialog-footer-actions">
<Button
className="LeftRightBtn bp3-intent-success"
text="确定"
onClick={() => store.OnOk(ModalState.Ok)}
/>
<Button className="LeftRightBtn bp3-intent-danger" text="取消"
onClick={() => store.OnOk(ModalState.Cancel)}
/>
</div>
</div>
</div>
</div>
</div>
);
}
}

@ -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';

@ -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<IConfigPRops, UserConfigState>{
});
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<IConfigPRops, UserConfigState>{
// 删除视图中的对应项
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<IConfigPRops, UserConfigState>{
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=
{

@ -72,7 +72,7 @@
}
}
//板名称输入框大小
#modal .br-name{
#boardModal>.board-config>.bp3-dialog-body .br-name{
width: @nameInput;
}
/* 排孔选项 */

@ -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
}
}
}

@ -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";

@ -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', () =>

@ -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()

@ -45,13 +45,9 @@ export class ToasterInput extends React.Component<IToasterInputProps, {}>
}
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<IToasterInputProps, {}>
{
//无效值不改变计算数据
}
if (this.props.onChange)
//值有效才运行change函数
if (this.hideErrorMsg && this.props.onChange)
this.props.onChange(e);
}
handleFocus = e =>

@ -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%;
}

@ -304,7 +304,3 @@ export class SpecialShapeStore extends BoardStore
thickness: 18
}
}
export class DoorStore extends BoardStore
{
title = "门板";
}

@ -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)
}
}

@ -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;
}
}
}

@ -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,
})
}
}
}
}

@ -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;
}

@ -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";

Loading…
Cancel
Save