mirror of https://gitee.com/cf-fz/WebCAD.git
!2031 功能:绘制门窗
parent
2bc2b2f56b
commit
c38e8a2275
@ -0,0 +1,74 @@
|
||||
import { app } from "../../ApplicationServices/Application";
|
||||
import { DuplicateRecordCloning } from "../../Common/Status";
|
||||
import { RoomHolePolyline } from "../../DatabaseServices/Room/Entity/Wall/Hole/RoomHolePolyline";
|
||||
import { DrawDoorWindowPanel } from "../../DatabaseServices/Room/Entity/Wall/Hole/Window/DrawWindowPanel";
|
||||
import { DoorWindowPanelStore } from "../../DatabaseServices/Room/Entity/Wall/Hole/Window/WindowPanelStore";
|
||||
import { TemplateRoomDoorRecord } from "../../DatabaseServices/Template/ProgramTempate/TemplateRoomDoorRecord";
|
||||
import { GetOnlineTemplate } from "../../DatabaseServices/Template/TempateUtils";
|
||||
import { TemplateRecord } from "../../DatabaseServices/Template/TemplateRecord";
|
||||
import { ModalState } from "../../UI/Components/Modal/ModalInterface";
|
||||
import { Command_DrawHole, DrawHoleType, IHoleType } from "./DrawHole";
|
||||
|
||||
export class Command_DrawRoomDoor extends Command_DrawHole
|
||||
{
|
||||
constructor(drawType: DrawHoleType, holeIType: IHoleType, private _IsOneKeyDraw: boolean = false)
|
||||
{
|
||||
super(drawType, holeIType);
|
||||
}
|
||||
|
||||
//一键画门配置
|
||||
async SetStoreParam(store: DoorWindowPanelStore) { }
|
||||
|
||||
override async BeferDrawHole(drawHoleType: DrawHoleType): Promise<ModalState>
|
||||
{
|
||||
//呼出对话框
|
||||
let store = DoorWindowPanelStore.GetSingleInstance();
|
||||
store.m_Option.Height = 2200;
|
||||
store.m_Option.Length = 800;
|
||||
|
||||
if (this._IsOneKeyDraw)
|
||||
{
|
||||
store.InitOption();
|
||||
this.SetStoreParam(store);
|
||||
}
|
||||
else
|
||||
{
|
||||
app.Editor.ModalManage.RenderModal(DrawDoorWindowPanel, { store, drawHoleType, holeIType: IHoleType.Door });
|
||||
let state = await app.Editor.ModalManage.Wait();
|
||||
if (state.Status !== ModalState.Ok)
|
||||
return ModalState.Cancel;
|
||||
}
|
||||
this.holeLength = store.m_Option.Length;
|
||||
this.holeHeight = store.m_Option.Height;
|
||||
return ModalState.Ok;
|
||||
}
|
||||
|
||||
override async AfterDrawHole(hole: RoomHolePolyline): Promise<void>
|
||||
{
|
||||
let store = DoorWindowPanelStore.GetSingleInstance();
|
||||
let tr = new TemplateRoomDoorRecord();//顶层节点
|
||||
tr.HoleObjectId = hole.Id;
|
||||
|
||||
tr.InitBaseParams();
|
||||
tr.InitHoleParams();
|
||||
|
||||
tr.GetParam("L").expr = store.m_Option.Length;
|
||||
tr.GetParam("H").expr = store.m_Option.Height;
|
||||
|
||||
tr.DoorLogo = store.currentDoorWindowsInfo?.temp?.logo;
|
||||
|
||||
app.Database.TemplateTable.Add(tr);
|
||||
|
||||
hole.Template = tr.Id;
|
||||
|
||||
let doorTr = await GetOnlineTemplate(store.currentDoorWindowsInfo?.temp?.id || "11777"); //窗户模板 默认ID:11777
|
||||
|
||||
for (let w of hole.FakerWalls)
|
||||
{
|
||||
let template = app.Database.WblockCloneObejcts([doorTr], app.Database.TemplateTable, new Map(), DuplicateRecordCloning.Ignore)[0] as TemplateRecord;
|
||||
tr.Children.push(template.Id);
|
||||
}
|
||||
|
||||
await tr.UpdateTemplateTree();
|
||||
}
|
||||
}
|
@ -0,0 +1,148 @@
|
||||
import { app } from "../../ApplicationServices/Application";
|
||||
import { DuplicateRecordCloning } from "../../Common/Status";
|
||||
import { RoomHolePolyline } from "../../DatabaseServices/Room/Entity/Wall/Hole/RoomHolePolyline";
|
||||
import { DrawDoorWindowPanel } from "../../DatabaseServices/Room/Entity/Wall/Hole/Window/DrawWindowPanel";
|
||||
import { DoorWindowPanelStore } from "../../DatabaseServices/Room/Entity/Wall/Hole/Window/WindowPanelStore";
|
||||
import { RoomWallArc } from "../../DatabaseServices/Room/Entity/Wall/RoomWallArc";
|
||||
import { TemplateArcWindowRecord } from "../../DatabaseServices/Template/ProgramTempate/TemplateArcWindowRecord";
|
||||
import { TemplateWindowRecord } from "../../DatabaseServices/Template/ProgramTempate/TemplateWindowRecord";
|
||||
import { GetOnlineTemplate } from "../../DatabaseServices/Template/TempateUtils";
|
||||
import { TemplateRecord } from "../../DatabaseServices/Template/TemplateRecord";
|
||||
import { ModalState } from "../../UI/Components/Modal/ModalInterface";
|
||||
import { Command_DrawHole, DrawHoleType, IHoleType } from "./DrawHole";
|
||||
|
||||
export class Command_DrawRoomWindow extends Command_DrawHole
|
||||
{
|
||||
constructor(drawType: DrawHoleType, holeIType: IHoleType, private _IsOneKeyDraw: boolean = false)
|
||||
{
|
||||
super(drawType, holeIType);
|
||||
}
|
||||
|
||||
//一键绘制窗户配置
|
||||
async SetStoreParam(store: DoorWindowPanelStore) { }
|
||||
|
||||
override async BeferDrawHole(drawHoleType: DrawHoleType): Promise<ModalState>
|
||||
{
|
||||
//呼出对话框
|
||||
let store = DoorWindowPanelStore.GetSingleInstance();
|
||||
if (this._IsOneKeyDraw)
|
||||
{
|
||||
store.InitOption();
|
||||
this.SetStoreParam(store);
|
||||
}
|
||||
else
|
||||
{
|
||||
app.Editor.ModalManage.RenderModal(DrawDoorWindowPanel, { store, drawHoleType, holeIType: IHoleType.Window });
|
||||
let state = await app.Editor.ModalManage.Wait();
|
||||
if (state.Status !== ModalState.Ok)
|
||||
return ModalState.Cancel;
|
||||
}
|
||||
this.holeLength = store.m_Option.Length;
|
||||
this.holeHeight = store.m_Option.Height;
|
||||
this.offGround = store.m_Option.WindowOffGround;
|
||||
return ModalState.Ok;
|
||||
}
|
||||
|
||||
override async AfterDrawHole(hole: RoomHolePolyline, drawHoleType: DrawHoleType): Promise<void>
|
||||
{
|
||||
let store = DoorWindowPanelStore.GetSingleInstance();
|
||||
let tr = new TemplateWindowRecord();//顶层节点
|
||||
|
||||
tr.HoleObjectId = hole.Id;
|
||||
|
||||
tr.InitBaseParams();
|
||||
tr.InitHoleParams();
|
||||
|
||||
tr.GetParam("WZ").expr = 25;//位置
|
||||
tr.GetParam("L").expr = store.m_Option.Length;
|
||||
tr.GetParam("H").expr = store.m_Option.Height;
|
||||
|
||||
if (drawHoleType === DrawHoleType.I)
|
||||
{
|
||||
if (store.m_Option.BayDist <= 1)
|
||||
store.m_Option.IsBayWindow = false;
|
||||
|
||||
tr.GetParam("WP").expr = store.m_Option.IsBayWindow ? store.m_Option.BayDist : 0;
|
||||
}
|
||||
else if (drawHoleType === DrawHoleType.L)
|
||||
{
|
||||
store.m_Option.IsBayWindow = store.m_Option.IsBayWindow && hole.FakerWalls.every(wall => !(wall instanceof RoomWallArc));
|
||||
tr.GetParam("ZWP").expr = store.m_Option.IsBayWindow ? store.m_Option.BayLeftDist : 0;
|
||||
tr.GetParam("YWP").expr = store.m_Option.IsBayWindow ? store.m_Option.BayRightDist : 0;
|
||||
}
|
||||
else if (drawHoleType === DrawHoleType.U)
|
||||
{
|
||||
store.m_Option.IsBayWindow = store.m_Option.IsBayWindow && hole.FakerWalls.every(wall => !(wall instanceof RoomWallArc));
|
||||
tr.GetParam("ZWP").expr = store.m_Option.IsBayWindow ? store.m_Option.BayLeftDist : 0;
|
||||
tr.GetParam("MWP").expr = store.m_Option.IsBayWindow ? store.m_Option.BayMiddleDist : 0;
|
||||
tr.GetParam("YWP").expr = store.m_Option.IsBayWindow ? store.m_Option.BayRightDist : 0;
|
||||
}
|
||||
|
||||
tr.GetParam("CTS").expr = store.m_Option.HasWindowStone ? 1 : 0;
|
||||
if (store.m_Option.HasWindowStone)
|
||||
{
|
||||
tr.GetParam("CTSH").expr = store.m_Option.StoneThick;
|
||||
tr.GetParam("CTSTC").expr = store.m_Option.StoneBulge;
|
||||
tr.GetParam("CTSZYTC").expr = store.m_Option.StoneLeftRightBulge;
|
||||
}
|
||||
|
||||
tr.LeftIsWall = store.m_Option.IsBayWindow ? store.m_Option.BayLeftIsWall : true;
|
||||
tr.RightIsWall = store.m_Option.IsBayWindow ? store.m_Option.BayRightIsWall : true;
|
||||
tr.WindowLogo = store.currentDoorWindowsInfo?.temp?.logo;
|
||||
|
||||
app.Database.TemplateTable.Add(tr);
|
||||
|
||||
hole.Template = tr.Id;
|
||||
|
||||
let windowTr = await GetOnlineTemplate(store.currentDoorWindowsInfo?.temp?.id || "11777"); //窗户模板 默认ID:11777
|
||||
|
||||
//左飘窗
|
||||
if (store.m_Option.IsBayWindow)
|
||||
{
|
||||
let leftWindowTemplateId = store.currentLeftBayWindowsInfo?.temp?.id || "11777";//窗户模板 默认ID:11777
|
||||
|
||||
tr.LeftWindowLogo = store.currentLeftBayWindowsInfo?.temp?.logo;
|
||||
tr.LeftWindowTemplateId = leftWindowTemplateId;
|
||||
if (!tr.LeftIsWall)
|
||||
{
|
||||
let leftWindowTr = await GetOnlineTemplate(leftWindowTemplateId);
|
||||
let template = app.Database.WblockCloneObejcts([leftWindowTr], app.Database.TemplateTable, new Map(), DuplicateRecordCloning.Ignore)[0] as TemplateRecord;
|
||||
tr.Children.push(template.Id);
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < hole.FakerWalls.length; i++)
|
||||
{
|
||||
if (hole.FakerWalls[i] instanceof RoomWallArc)
|
||||
{
|
||||
let template = new TemplateArcWindowRecord();
|
||||
template.InitBaseParams();
|
||||
app.Database.TemplateTable.Add(template);
|
||||
template.InitWindowFrame(hole, i);
|
||||
tr.Children.push(template.Id);
|
||||
}
|
||||
else
|
||||
{
|
||||
let template = app.Database.WblockCloneObejcts([windowTr], app.Database.TemplateTable, new Map(), DuplicateRecordCloning.Ignore)[0] as TemplateRecord;
|
||||
tr.Children.push(template.Id);
|
||||
}
|
||||
}
|
||||
|
||||
//右飘窗
|
||||
if (store.m_Option.IsBayWindow)
|
||||
{
|
||||
let rightWindowTemplateId = store.currentRightBayWindowsInfo?.temp?.id || "11777";//窗户模板 默认ID:11777
|
||||
|
||||
tr.RightWindowLogo = store.currentRightBayWindowsInfo?.temp?.logo;
|
||||
tr.RightWindowTemplateId = rightWindowTemplateId;
|
||||
if (!tr.RightIsWall)
|
||||
{
|
||||
let rightWindowTr = await GetOnlineTemplate(rightWindowTemplateId);
|
||||
let template = app.Database.WblockCloneObejcts([rightWindowTr], app.Database.TemplateTable, new Map(), DuplicateRecordCloning.Ignore)[0] as TemplateRecord;
|
||||
tr.Children.push(template.Id);
|
||||
}
|
||||
}
|
||||
|
||||
await tr.UpdateTemplateTree();
|
||||
}
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
import { DoorWindowPanelStore } from "../../DatabaseServices/Room/Entity/Wall/Hole/Window/WindowPanelStore";
|
||||
import { Command_DrawRoomDoor } from "./DrawRoomDoor";
|
||||
import { Command_DrawRoomWindow } from "./DrawRoomWindow";
|
||||
|
||||
export class Command_OneKeyDrawYZCWindow extends Command_DrawRoomWindow
|
||||
{
|
||||
override async SetStoreParam(store: DoorWindowPanelStore): Promise<void>
|
||||
{
|
||||
//一字窗
|
||||
store.m_Option.Length = 1800;
|
||||
store.m_Option.Height = 1500;
|
||||
store.m_Option.Thick = 280;
|
||||
store.m_Option.IsBayWindow = false;
|
||||
}
|
||||
}
|
||||
|
||||
export class Command_OneKeyDrawLDCWindow extends Command_DrawRoomWindow
|
||||
{
|
||||
override async SetStoreParam(store: DoorWindowPanelStore): Promise<void>
|
||||
{
|
||||
//落地窗
|
||||
store.m_Option.Length = 3000;
|
||||
store.m_Option.Height = 2000;
|
||||
store.m_Option.Thick = 280;
|
||||
store.m_Option.WindowOffGround = 0;
|
||||
store.m_Option.IsBayWindow = false;
|
||||
}
|
||||
}
|
||||
|
||||
export class Command_OneKeyDrawPCWindow extends Command_DrawRoomWindow
|
||||
{
|
||||
override async SetStoreParam(store: DoorWindowPanelStore): Promise<void>
|
||||
{
|
||||
//飘窗
|
||||
store.m_Option.Length = 1900;
|
||||
store.m_Option.Height = 1750;
|
||||
store.m_Option.BayDist = 600;
|
||||
store.m_Option.IsBayWindow = true;
|
||||
}
|
||||
}
|
||||
|
||||
export class Command_OneKeyDrawZJCWindow extends Command_DrawRoomWindow
|
||||
{
|
||||
override async SetStoreParam(store: DoorWindowPanelStore): Promise<void>
|
||||
{
|
||||
//转角窗
|
||||
store.m_Option.Height = 1500;
|
||||
store.m_Option.IsBayWindow = false;
|
||||
store.m_Option.BayLeftIsWall = true;
|
||||
store.m_Option.BayRightIsWall = true;
|
||||
}
|
||||
}
|
||||
|
||||
export class Command_OneKeyDrawZJPCWindow extends Command_DrawRoomWindow
|
||||
{
|
||||
override async SetStoreParam(store: DoorWindowPanelStore): Promise<void>
|
||||
{
|
||||
//转角飘窗
|
||||
store.m_Option.Height = 1500;
|
||||
store.m_Option.IsBayWindow = true;
|
||||
store.m_Option.BayLeftDist = 600;
|
||||
store.m_Option.BayRightDist = 600;
|
||||
}
|
||||
}
|
||||
|
||||
export class Command_OneKeyDrawYJHMWindow extends Command_DrawRoomDoor
|
||||
{
|
||||
override async SetStoreParam(store: DoorWindowPanelStore): Promise<void>
|
||||
{
|
||||
//一键画门
|
||||
store.m_Option.Height = 2200;
|
||||
store.m_Option.Length = 800;
|
||||
}
|
||||
}
|
@ -0,0 +1,295 @@
|
||||
import { Button, Checkbox, Classes, Collapse, Divider, Icon } from "@blueprintjs/core";
|
||||
import { observable } from "mobx";
|
||||
import { observer } from "mobx-react";
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
import { DrawHoleType, IHoleType } from "../../../../../../Add-on/Room/DrawHole";
|
||||
import { app } from "../../../../../../ApplicationServices/Application";
|
||||
import { ModalState } from "../../../../../../UI/Components/Modal/ModalInterface";
|
||||
import { Location } from "../../../../../../UI/Components/ToolBar/ModifyModel/RoomBaseParams";
|
||||
import { DoorWindowPanelStore, DoorWindowParamsNames } from "./WindowPanelStore";
|
||||
import { WindowParamsComponent } from "./WindowParamsComponent";
|
||||
import { DrawWindowTempInfo } from "./WindowTempInfo";
|
||||
import { WindowTempSelect } from "./WindowTempSelect";
|
||||
|
||||
export enum Visibility
|
||||
{
|
||||
Visible = "visible",
|
||||
Hidden = "hidden",
|
||||
}
|
||||
|
||||
@observer
|
||||
export class DrawDoorWindowPanel extends React.Component<{ store: DoorWindowPanelStore; drawHoleType: DrawHoleType; holeIType: IHoleType; }>
|
||||
{
|
||||
private _CameraStateContainer: HTMLElement;
|
||||
private startLocation = observable.box(Location.Middle);
|
||||
|
||||
constructor(props)
|
||||
{
|
||||
super(props);
|
||||
this._CameraStateContainer = document.createElement('div');
|
||||
this._CameraStateContainer.id = 'template-select';
|
||||
this._CameraStateContainer.style.zIndex = "99";
|
||||
document.getElementById('modal').appendChild(this._CameraStateContainer);
|
||||
|
||||
if (window.screen.width <= 1450)
|
||||
this._CameraStateContainer.style.left = '120px';
|
||||
else
|
||||
this._CameraStateContainer.style.left = `calc(50vw - 650px)`;
|
||||
|
||||
if (window.screen.height <= 750)
|
||||
this._CameraStateContainer.style.top = `0px`;
|
||||
else
|
||||
this._CameraStateContainer.style.top = `calc(50vh - 425px)`;
|
||||
|
||||
this._CameraStateContainer.style.visibility = Visibility.Hidden;
|
||||
|
||||
ReactDOM.render(<WindowTempSelect
|
||||
selectDiv={this._CameraStateContainer}
|
||||
store={this.props.store}
|
||||
filter={["门窗"]}
|
||||
location={this.startLocation}
|
||||
/>, this._CameraStateContainer);
|
||||
}
|
||||
|
||||
componentWillUnmount()
|
||||
{
|
||||
document.getElementById('modal').removeChild(this._CameraStateContainer);
|
||||
this._CameraStateContainer = undefined;
|
||||
}
|
||||
|
||||
private startSelectTemplate(style: Visibility)
|
||||
{
|
||||
this._CameraStateContainer.style.visibility = style;
|
||||
};
|
||||
|
||||
render()
|
||||
{
|
||||
let store = this.props.store;
|
||||
return (
|
||||
<div id="commonModal" className={Classes.DIALOG_CONTAINER}>
|
||||
<div id="DrawWindowPanel" className={Classes.DIALOG} style={{ height: "100%" }}>
|
||||
<div className={Classes.DIALOG_HEADER} data-id="dragArea">
|
||||
<Icon icon="widget" iconSize={18} />
|
||||
<h4 className={Classes.HEADING}>门窗参数</h4>
|
||||
<Button
|
||||
icon="cross"
|
||||
aria-label="Close"
|
||||
minimal={true}
|
||||
onClick={() => { app.Editor.ModalManage.Destory(); }}
|
||||
/>
|
||||
</div>
|
||||
<div className={Classes.DIALOG_BODY}>
|
||||
<div className='windowInfo'>
|
||||
<DrawWindowTempInfo
|
||||
store={store}
|
||||
logo={this.props.store.currentDoorWindowsInfo?.temp?.logo}
|
||||
showSizeInfo
|
||||
startLocation={this.startLocation}
|
||||
location={Location.Middle}
|
||||
interactive
|
||||
selectDiv={this._CameraStateContainer}
|
||||
/>
|
||||
</div>
|
||||
<div className='paramsSize'>
|
||||
{
|
||||
this.props.drawHoleType === DrawHoleType.I &&
|
||||
<WindowParamsComponent
|
||||
store={this.props.store}
|
||||
sizeKey={DoorWindowParamsNames.Length}
|
||||
sliderMin={100}
|
||||
sliderMax={5000}
|
||||
title={"宽度"}
|
||||
/>
|
||||
}
|
||||
<WindowParamsComponent
|
||||
store={this.props.store}
|
||||
sizeKey={DoorWindowParamsNames.Height}
|
||||
sliderMin={100}
|
||||
sliderMax={5000}
|
||||
title={"高度"}
|
||||
/>
|
||||
{
|
||||
this.props.holeIType === IHoleType.Window && <WindowParamsComponent
|
||||
store={this.props.store}
|
||||
sizeKey={DoorWindowParamsNames.WindowOffGround}
|
||||
sliderMin={0}
|
||||
sliderMax={5000}
|
||||
title={"离地"}
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
{
|
||||
this.props.holeIType === IHoleType.Window && <div>
|
||||
<Divider />
|
||||
<div className="bayWindow">
|
||||
<Checkbox
|
||||
label="飘窗"
|
||||
checked={this.props.store.m_Option.IsBayWindow}
|
||||
onChange={() =>
|
||||
{
|
||||
this.props.store.m_Option.IsBayWindow = !this.props.store.m_Option.IsBayWindow;
|
||||
}}
|
||||
/>
|
||||
<Collapse isOpen={this.props.store.m_Option.IsBayWindow}>
|
||||
<div className="bayWindowParam">
|
||||
<Checkbox
|
||||
label="飘窗左侧是墙"
|
||||
checked={this.props.store.m_Option.BayLeftIsWall}
|
||||
onChange={() =>
|
||||
{
|
||||
this.props.store.m_Option.BayLeftIsWall = !this.props.store.m_Option.BayLeftIsWall;
|
||||
}}
|
||||
/>
|
||||
<Checkbox
|
||||
label="飘窗右侧是墙"
|
||||
checked={this.props.store.m_Option.BayRightIsWall}
|
||||
onChange={() =>
|
||||
{
|
||||
this.props.store.m_Option.BayRightIsWall = !this.props.store.m_Option.BayRightIsWall;
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div style={{ display: "flex", justifyContent: "space-around" }}>
|
||||
<DrawWindowTempInfo
|
||||
store={store}
|
||||
logo={store.currentLeftBayWindowsInfo?.temp?.logo}
|
||||
interactive={!store.m_Option.BayLeftIsWall}
|
||||
selectDiv={this._CameraStateContainer}
|
||||
startLocation={this.startLocation}
|
||||
location={Location.Left}
|
||||
/>
|
||||
<DrawWindowTempInfo
|
||||
store={store}
|
||||
logo={store.currentRightBayWindowsInfo?.temp?.logo}
|
||||
interactive={!store.m_Option.BayRightIsWall}
|
||||
selectDiv={this._CameraStateContainer}
|
||||
startLocation={this.startLocation}
|
||||
location={Location.Right}
|
||||
/>
|
||||
</div>
|
||||
<div className='paramsSize'>
|
||||
{
|
||||
this.props.drawHoleType === DrawHoleType.I &&
|
||||
<WindowParamsComponent
|
||||
store={this.props.store}
|
||||
sizeKey={DoorWindowParamsNames.BayDist}
|
||||
sliderMin={100}
|
||||
sliderMax={2000}
|
||||
title={"外飘距离"}
|
||||
/>
|
||||
}
|
||||
{
|
||||
this.props.drawHoleType !== DrawHoleType.I &&
|
||||
<WindowParamsComponent
|
||||
store={this.props.store}
|
||||
sizeKey={DoorWindowParamsNames.BayLeftDist}
|
||||
sliderMin={100}
|
||||
sliderMax={2000}
|
||||
title={"左飘距离"}
|
||||
/>
|
||||
}
|
||||
{
|
||||
this.props.drawHoleType === DrawHoleType.U &&
|
||||
<WindowParamsComponent
|
||||
store={this.props.store}
|
||||
sizeKey={DoorWindowParamsNames.BayMiddleDist}
|
||||
sliderMin={100}
|
||||
sliderMax={2000}
|
||||
title={"中飘距离"}
|
||||
/>
|
||||
}
|
||||
{
|
||||
this.props.drawHoleType !== DrawHoleType.I &&
|
||||
<WindowParamsComponent
|
||||
store={this.props.store}
|
||||
sizeKey={DoorWindowParamsNames.BayRightDist}
|
||||
sliderMin={100}
|
||||
sliderMax={2000}
|
||||
title={"右飘距离"}
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
</Collapse>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
{
|
||||
this.props.holeIType === IHoleType.Window && <div>
|
||||
<Divider />
|
||||
<div className="stone">
|
||||
<Checkbox
|
||||
label="窗台石"
|
||||
checked={this.props.store.m_Option.HasWindowStone}
|
||||
onChange={() =>
|
||||
{
|
||||
this.props.store.m_Option.HasWindowStone = !this.props.store.m_Option.HasWindowStone;
|
||||
}}
|
||||
/>
|
||||
<Collapse isOpen={this.props.store.m_Option.HasWindowStone}>
|
||||
<div className='paramsSize'>
|
||||
<WindowParamsComponent
|
||||
store={this.props.store}
|
||||
sizeKey={DoorWindowParamsNames.StoneThick}
|
||||
sliderMin={0}
|
||||
sliderMax={200}
|
||||
title={"台面厚度"}
|
||||
/>
|
||||
<WindowParamsComponent
|
||||
store={this.props.store}
|
||||
sizeKey={DoorWindowParamsNames.StoneBulge}
|
||||
sliderMin={0}
|
||||
sliderMax={200}
|
||||
title={"台面凸出"}
|
||||
/>
|
||||
<WindowParamsComponent
|
||||
store={this.props.store}
|
||||
sizeKey={DoorWindowParamsNames.StoneLeftRightBulge}
|
||||
sliderMin={0}
|
||||
sliderMax={200}
|
||||
title={"侧面凸出"}
|
||||
/>
|
||||
</div>
|
||||
</Collapse>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<div className={Classes.DIALOG_FOOTER}>
|
||||
<div className={Classes.DIALOG_FOOTER_ACTIONS}>
|
||||
<div className="foot_right">
|
||||
<Button
|
||||
className="LeftRightBtn bp3-intent-success"
|
||||
text="选择模板"
|
||||
onClick={() =>
|
||||
{
|
||||
this.startLocation.set(Location.All);
|
||||
this.startSelectTemplate(Visibility.Visible);
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
intent="success"
|
||||
text="确定"
|
||||
onClick={() =>
|
||||
{
|
||||
app.Editor.ModalManage.m_PromisRes({ Status: ModalState.Ok });
|
||||
app.Editor.ModalManage.Destory();
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
intent="danger"
|
||||
text="取消"
|
||||
onClick={() =>
|
||||
{
|
||||
app.Editor.ModalManage.m_PromisRes({ Status: ModalState.Cancel });
|
||||
app.Editor.ModalManage.Destory();
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div >
|
||||
</div >
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
import { observable, toJS } from "mobx";
|
||||
import { DefaultWindowPanelOption as DefaultDoorWindowPanelOption } from "../../../../../../Editor/DefaultConfig";
|
||||
import { IConfigOption } from "../../../../../../UI/Components/Board/UserConfig";
|
||||
import { WindowPanelConfigOption as DoorWindowPanelConfigOption } from "../../../../../../UI/Store/BoardInterface";
|
||||
import { IConfigStore } from "../../../../../../UI/Store/BoardStore";
|
||||
import { ISelectTempInfo } from "../../../../../../UI/Store/DoorInterface";
|
||||
import { TemplateWindowRecord } from "../../../../../Template/ProgramTempate/TemplateWindowRecord";
|
||||
|
||||
export enum DoorWindowParamsNames
|
||||
{
|
||||
Length = "Length",
|
||||
Height = "Height",
|
||||
Thick = "Thick",
|
||||
WindowOffGround = "WindowOffGround",
|
||||
IsBayWindow = "IsBayWindow",
|
||||
BayLeftIsWall = "BayLeftIsWall",
|
||||
BayRightIsWall = "BayRightIsWall",
|
||||
BayDist = "BayDist",
|
||||
BayLeftDist = "BayLeftDist",
|
||||
BayMiddleDist = "BayMiddleDist",
|
||||
BayRightDist = "BayRightDist",
|
||||
HasWindowStone = "HasWindowStone",
|
||||
StoneThick = "StoneThick",
|
||||
StoneBulge = "StoneBulge",
|
||||
StoneLeftRightBulge = "StoneLeftRightBulge",
|
||||
}
|
||||
|
||||
export class DoorWindowPanelStore implements IConfigStore
|
||||
{
|
||||
@observable configName = "默认";
|
||||
@observable m_Option: DoorWindowPanelConfigOption = { ...DefaultDoorWindowPanelOption };
|
||||
@observable configsNames: string[] = [];
|
||||
@observable selectTemplateInfo: ISelectTempInfo = { temp: { id: "", name: "", logo: "" } };
|
||||
@observable currentDoorWindowsInfo: ISelectTempInfo; //应用的门窗信息
|
||||
@observable currentLeftBayWindowsInfo: ISelectTempInfo; //应用的左飘窗信息
|
||||
@observable currentRightBayWindowsInfo: ISelectTempInfo; //应用的右飘窗信息
|
||||
|
||||
SaveConfig()
|
||||
{
|
||||
let newConfig: IConfigOption = {};
|
||||
newConfig.option = toJS(this.m_Option);
|
||||
return newConfig;
|
||||
};
|
||||
|
||||
InitOption()
|
||||
{
|
||||
Object.assign(this.m_Option, DefaultDoorWindowPanelOption);
|
||||
this.currentDoorWindowsInfo = undefined;
|
||||
this.currentLeftBayWindowsInfo = undefined;
|
||||
this.currentRightBayWindowsInfo = undefined;
|
||||
}
|
||||
|
||||
InitCurrentWindowOption(windowTemp: TemplateWindowRecord)
|
||||
{
|
||||
if (!windowTemp) return;
|
||||
this.m_Option.BayLeftIsWall = windowTemp.LeftIsWall;
|
||||
this.m_Option.BayRightIsWall = windowTemp.RightIsWall;
|
||||
}
|
||||
|
||||
UpdateOption(cof: IConfigOption<DoorWindowPanelConfigOption>)
|
||||
{
|
||||
this.m_Option = cof.option;
|
||||
}
|
||||
|
||||
private static _SingleInstance: DoorWindowPanelStore;
|
||||
static GetSingleInstance(): DoorWindowPanelStore
|
||||
{
|
||||
if (this._SingleInstance) return this._SingleInstance;
|
||||
this._SingleInstance = new DoorWindowPanelStore;
|
||||
return this._SingleInstance;
|
||||
}
|
||||
}
|
@ -0,0 +1,101 @@
|
||||
import { Intent, NumericInput, Position, Slider, Tooltip } from "@blueprintjs/core";
|
||||
import { observable } from "mobx";
|
||||
import { observer } from "mobx-react";
|
||||
import React from "react";
|
||||
import { safeEval } from "../../../../../../Common/eval";
|
||||
import { KeyBoard } from "../../../../../../Common/KeyEnum";
|
||||
import { DoorWindowPanelStore } from "./WindowPanelStore";
|
||||
|
||||
|
||||
interface SizeComponentProps
|
||||
{
|
||||
store: DoorWindowPanelStore;
|
||||
title: string; //标题提示字符串
|
||||
sizeKey: string; //字段
|
||||
sliderMin: number;
|
||||
sliderMax: number;
|
||||
}
|
||||
@observer
|
||||
export class WindowParamsComponent extends React.Component<SizeComponentProps>
|
||||
{
|
||||
@observable _Value: number = parseInt(this.props.store.m_Option[this.props.sizeKey]);
|
||||
@observable _IsPopoverOpen: boolean = false;
|
||||
_SizeRef = React.createRef<NumericInput>();
|
||||
|
||||
render()
|
||||
{
|
||||
let store = this.props.store;
|
||||
return (
|
||||
<div className='windowParamsSlider'>
|
||||
<span>{this.props.title}</span>
|
||||
<Slider
|
||||
min={this.props.sliderMin}
|
||||
max={this.props.sliderMax}
|
||||
value={this._Value}
|
||||
onChange={(value) =>
|
||||
{
|
||||
this._Value = value;
|
||||
this._SizeRef.current.inputElement.value = value.toString();
|
||||
}}
|
||||
onRelease={(value) =>
|
||||
{
|
||||
store.m_Option[this.props.sizeKey] = value;
|
||||
}}
|
||||
/>
|
||||
<Tooltip
|
||||
content={"仅限" + this.props.sliderMin + "-" + this.props.sliderMax + "间的数字!"}
|
||||
position={Position.TOP}
|
||||
intent={Intent.WARNING}
|
||||
isOpen={this._IsPopoverOpen}
|
||||
>
|
||||
|
||||
<NumericInput
|
||||
min={this.props.sliderMin}
|
||||
max={this.props.sliderMax}
|
||||
defaultValue={this._Value}
|
||||
ref={this._SizeRef}
|
||||
onValueChange={(s, n, e) =>
|
||||
{
|
||||
let val = safeEval(e.value);
|
||||
if (!isNaN(val))
|
||||
{
|
||||
if (val < this.props.sliderMin || val > this.props.sliderMax)
|
||||
this._IsPopoverOpen = true;
|
||||
else
|
||||
this._IsPopoverOpen = false;
|
||||
}
|
||||
else
|
||||
this._IsPopoverOpen = true;
|
||||
}}
|
||||
onKeyDown={(e) =>
|
||||
{
|
||||
if (e.keyCode === KeyBoard.Enter)
|
||||
{
|
||||
this._SizeRef.current.inputElement.blur();
|
||||
}
|
||||
else if (e.keyCode === KeyBoard.Escape)
|
||||
{
|
||||
this._SizeRef.current.inputElement.value = store.m_Option[this.props.sizeKey].toFixed();
|
||||
this._SizeRef.current.inputElement.blur();
|
||||
}
|
||||
e.stopPropagation();
|
||||
}}
|
||||
onBlur={(e) =>
|
||||
{
|
||||
if (this._IsPopoverOpen)
|
||||
{
|
||||
e.target.value = store.m_Option[this.props.sizeKey];
|
||||
this._IsPopoverOpen = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
this._Value = parseFloat(e.currentTarget.value);
|
||||
store.m_Option[this.props.sizeKey] = parseFloat(e.currentTarget.value);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</Tooltip>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,180 @@
|
||||
import { Card, Elevation, Icon } from "@blueprintjs/core";
|
||||
import { IObservableValue, observable } from "mobx";
|
||||
import { observer } from "mobx-react";
|
||||
import React from "react";
|
||||
import { app } from "../../../../../../ApplicationServices/Application";
|
||||
import { CURRENT_HOST } from "../../../../../../Common/HostUrl";
|
||||
import { DuplicateRecordCloning } from "../../../../../../Common/Status";
|
||||
import { CommandWrap } from "../../../../../../Editor/CommandMachine";
|
||||
import { ModalState } from "../../../../../../UI/Components/Modal/ModalInterface";
|
||||
import { Location } from "../../../../../../UI/Components/ToolBar/ModifyModel/RoomBaseParams";
|
||||
import { TemplateArcWindowRecord } from "../../../../../Template/ProgramTempate/TemplateArcWindowRecord";
|
||||
import { TemplateRoomDoorRecord } from "../../../../../Template/ProgramTempate/TemplateRoomDoorRecord";
|
||||
import { TemplateWindowRecord } from "../../../../../Template/ProgramTempate/TemplateWindowRecord";
|
||||
import { DeleteTempate, GetOnlineTemplate, ReplaceTemplate } from "../../../../../Template/TempateUtils";
|
||||
import { TemplateRecord } from "../../../../../Template/TemplateRecord";
|
||||
import { RoomHolePolyline } from "../RoomHolePolyline";
|
||||
import { Visibility } from "./DrawWindowPanel";
|
||||
import { DoorWindowPanelStore } from "./WindowPanelStore";
|
||||
import { WindowTempSelect } from "./WindowTempSelect";
|
||||
|
||||
interface WindowTempInfoProps
|
||||
{
|
||||
store: DoorWindowPanelStore;
|
||||
doorWindowTemp?: TemplateWindowRecord | TemplateRoomDoorRecord;
|
||||
logo?: string;
|
||||
startLocation?: IObservableValue<string>;
|
||||
location?: string;
|
||||
showSizeInfo?: boolean;
|
||||
interactive?: boolean;
|
||||
selectDiv?: HTMLElement;
|
||||
}
|
||||
|
||||
@observer
|
||||
export class WindowTempInfo extends React.Component<WindowTempInfoProps>
|
||||
{
|
||||
@observable logo: string = this.props.logo;
|
||||
render()
|
||||
{
|
||||
let store = this.props.store;
|
||||
return (
|
||||
<div id='WindowTempInfo'>
|
||||
<Card className="windowImg"
|
||||
interactive
|
||||
elevation={Elevation.TWO}
|
||||
onClick={this.startSelectTemplate}
|
||||
>
|
||||
{
|
||||
this.logo ? <img
|
||||
src={`${CURRENT_HOST}/${this.logo}`}
|
||||
/> : <Icon iconSize={30} icon="add-to-artifact" />
|
||||
}
|
||||
<Icon iconSize={11} icon="swap-horizontal" className="changeLogo" />
|
||||
</Card>
|
||||
<div className="windowParamInfo">
|
||||
<span>{this.props.doorWindowTemp?.Name || "默认"}</span>
|
||||
<span>{store.m_Option.Length}*{store.m_Option.Height}*{store.m_Option.Thick}</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
private startSelectTemplate = async () =>
|
||||
{
|
||||
this.props.store.selectTemplateInfo.temp = { id: "", name: "", logo: this.logo };
|
||||
app.Editor.ModalManage.RenderModal(WindowTempSelect, { store: this.props.store, filter: ["门窗"] });
|
||||
let state = await app.Editor.ModalManage.Wait();
|
||||
if (state.Status === ModalState.Ok)
|
||||
{
|
||||
CommandWrap(async () =>
|
||||
{
|
||||
for (let index of this.getWindowLocation())
|
||||
{
|
||||
let oldTr = this.props.doorWindowTemp.Children[index].Object as TemplateRecord;
|
||||
if (oldTr instanceof TemplateArcWindowRecord) continue; //弧形窗
|
||||
let selectWindowTr = await GetOnlineTemplate(this.props.store.currentDoorWindowsInfo.temp.id || "11777");
|
||||
let newTr = app.Database.WblockCloneObejcts([selectWindowTr], app.Database.TemplateTable, new Map(), DuplicateRecordCloning.Ignore)[0] as TemplateRecord;
|
||||
|
||||
//记录左右飘窗Tr.id
|
||||
if (this.props.location === Location.Right)
|
||||
(this.props.doorWindowTemp as TemplateWindowRecord).RightWindowTemplateId = this.props.store.currentDoorWindowsInfo.temp.id || "11777";
|
||||
else if (this.props.location === Location.Left)
|
||||
(this.props.doorWindowTemp as TemplateWindowRecord).LeftWindowTemplateId = this.props.store.currentDoorWindowsInfo.temp.id || "11777";
|
||||
|
||||
await ReplaceTemplate(oldTr, newTr, false, true);
|
||||
DeleteTempate(oldTr);
|
||||
}
|
||||
await this.props.doorWindowTemp.UpdateTemplateTree();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @return {*} {number[]} 单个object所处下标
|
||||
* @memberof WindowTempInfo
|
||||
*/
|
||||
private getWindowLocation(): number[]
|
||||
{
|
||||
let strs = [];
|
||||
|
||||
this.logo = this.props.store.currentDoorWindowsInfo.temp.logo;
|
||||
if (this.props.doorWindowTemp instanceof TemplateWindowRecord)
|
||||
{
|
||||
//窗
|
||||
let isBayWindow = this.props.doorWindowTemp.WpDists.every(x => x !== 0);
|
||||
|
||||
//object[] => strs[]
|
||||
if (isBayWindow && !this.props.doorWindowTemp.LeftIsWall)
|
||||
strs.push(Location.Left);
|
||||
|
||||
let hole = this.props.doorWindowTemp.HoleObjectId.Object as RoomHolePolyline;
|
||||
for (let w of hole.FakerWalls)
|
||||
strs.push(Location.Middle);
|
||||
|
||||
if (isBayWindow && !this.props.doorWindowTemp.RightIsWall)
|
||||
strs.push(Location.Right);
|
||||
|
||||
//return [对应下标]
|
||||
if (this.props.location === Location.Middle)
|
||||
{
|
||||
this.props.doorWindowTemp.WindowLogo = this.props.store.currentDoorWindowsInfo.temp.logo;
|
||||
let indexs = [];
|
||||
for (let i = 0; i < hole.FakerWalls.length; i++)
|
||||
indexs.push(strs.indexOf(this.props.location) + i);
|
||||
return indexs;
|
||||
}
|
||||
else if (this.props.location === Location.Right)
|
||||
this.props.doorWindowTemp.RightWindowLogo = this.props.store.currentDoorWindowsInfo.temp.logo;
|
||||
else if (this.props.location === Location.Left)
|
||||
this.props.doorWindowTemp.LeftWindowLogo = this.props.store.currentDoorWindowsInfo.temp.logo;
|
||||
|
||||
return [strs.indexOf(this.props.location)];
|
||||
}
|
||||
else
|
||||
{
|
||||
//门
|
||||
this.props.doorWindowTemp.DoorLogo = this.props.store.currentDoorWindowsInfo.temp.logo;
|
||||
return [0];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@observer
|
||||
export class DrawWindowTempInfo extends React.Component<WindowTempInfoProps>
|
||||
{
|
||||
render()
|
||||
{
|
||||
let store = this.props.store;
|
||||
return (
|
||||
<div id='WindowTempInfo'>
|
||||
<Card className="windowImg"
|
||||
interactive={this.props.interactive}
|
||||
elevation={Elevation.TWO}
|
||||
onClick={this.startSelectTemplate}
|
||||
>
|
||||
{
|
||||
this.props.logo ? <img
|
||||
src={`${CURRENT_HOST}/${this.props.logo}`}
|
||||
/> : <Icon iconSize={30} icon="add-to-artifact" />
|
||||
}
|
||||
</Card>
|
||||
{
|
||||
this.props.showSizeInfo &&
|
||||
<div className="windowParamInfo">
|
||||
<span>默认</span>
|
||||
<span>{store.m_Option.Length}*{store.m_Option.Height}*{store.m_Option.Thick}</span>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
private startSelectTemplate = () =>
|
||||
{
|
||||
if (!this.props.interactive) return;
|
||||
this.props.startLocation.set(this.props.location);
|
||||
this.props.selectDiv.style.visibility = Visibility.Visible;
|
||||
};
|
||||
}
|
@ -0,0 +1,200 @@
|
||||
import { Button, Classes } from "@blueprintjs/core";
|
||||
import { IObservableValue, observable } from "mobx";
|
||||
import { observer } from "mobx-react";
|
||||
import React from "react";
|
||||
import { app } from "../../../../../../ApplicationServices/Application";
|
||||
import { TemplateUrls } from "../../../../../../Common/HostUrl";
|
||||
import { KeyBoard } from "../../../../../../Common/KeyEnum";
|
||||
import { DirectoryId } from "../../../../../../Common/Request";
|
||||
import { ModalFooter, ModalHeader } from "../../../../../../UI/Components/Modal/ModalContainer";
|
||||
import { ModalState } from "../../../../../../UI/Components/Modal/ModalInterface";
|
||||
import { CommonPanel } from "../../../../../../UI/Components/SourceManage/CommonPanel";
|
||||
import { TemplateList } from "../../../../../../UI/Components/Template/TemplateList";
|
||||
import { Location } from "../../../../../../UI/Components/ToolBar/ModifyModel/RoomBaseParams";
|
||||
import { IDrawerDoorTempInfo } from "../../../../../../UI/Store/DoorInterface";
|
||||
import { ITemplateParam } from "../../../../../../UI/Store/RightPanelStore/ITemplateParam";
|
||||
import { Visibility } from "./DrawWindowPanel";
|
||||
import { DoorWindowPanelStore } from "./WindowPanelStore";
|
||||
|
||||
export interface IWindowTempSelectProps
|
||||
{
|
||||
selectDiv?: HTMLElement;
|
||||
store: DoorWindowPanelStore;
|
||||
filter: string[],
|
||||
location?: IObservableValue<string>;
|
||||
}
|
||||
|
||||
@observer
|
||||
export class WindowTempSelect extends React.Component<IWindowTempSelectProps, {}> {
|
||||
@observable private currentProps: ITemplateParam[] = [];
|
||||
@observable private currentInfo: IDrawerDoorTempInfo = { id: "", name: "" };
|
||||
private container: HTMLElement;
|
||||
constructor(props)
|
||||
{
|
||||
super(props);
|
||||
}
|
||||
|
||||
componentDidMount()
|
||||
{
|
||||
this.container.addEventListener("keydown", e =>
|
||||
{
|
||||
if (e.keyCode === KeyBoard.Escape)
|
||||
{
|
||||
this.handleClose(ModalState.Cancel);
|
||||
}
|
||||
else if (e.keyCode === KeyBoard.Space || e.keyCode === KeyBoard.Enter)
|
||||
{
|
||||
this.applySelectTemp();
|
||||
this.handleClose(ModalState.Ok);
|
||||
}
|
||||
e.stopPropagation();
|
||||
});
|
||||
this.container.focus();
|
||||
|
||||
if (!this.props.store.selectTemplateInfo)
|
||||
{
|
||||
if (this.props.store instanceof DoorWindowPanelStore)
|
||||
{
|
||||
this.props.store.selectTemplateInfo = {
|
||||
temp: { id: "", name: "", logo: "", title: "选择窗户" },
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public render()
|
||||
{
|
||||
return (
|
||||
<div
|
||||
className={Classes.DIALOG + " template-select"}
|
||||
ref={el => this.container = el}
|
||||
tabIndex={-1}
|
||||
>
|
||||
<ModalHeader
|
||||
icon="bold"
|
||||
title="模板"
|
||||
close={() => { this.handleClose(ModalState.Cancel); }}
|
||||
/>
|
||||
<div
|
||||
className={Classes.DIALOG_BODY}
|
||||
>
|
||||
<CommonPanel
|
||||
loadCacheDirKey={"selectWindow"}
|
||||
defaultDirId={DirectoryId.TemplateDir}
|
||||
canDelete={false}
|
||||
getUrl={TemplateUrls.list}
|
||||
deleteUrl={TemplateUrls.delete}
|
||||
clickTree={() =>
|
||||
{
|
||||
this.currentProps.length = 0;
|
||||
}}
|
||||
dirNameFilter={this.props.filter}
|
||||
>
|
||||
<TemplateList
|
||||
currentProps={this.currentProps}
|
||||
currentInfo={this.currentInfo}
|
||||
forbidDelete={true}
|
||||
hideSelectBox={true}
|
||||
selectInfo={this.props.store.selectTemplateInfo}
|
||||
isShowDetail={false}
|
||||
/>
|
||||
</CommonPanel>
|
||||
</div>
|
||||
<ModalFooter hasConfig={false} style={{ width: "100%" }}>
|
||||
<Button
|
||||
className={Classes.INTENT_SUCCESS}
|
||||
text="应用"
|
||||
onClick={() =>
|
||||
{
|
||||
this.applySelectTemp();
|
||||
this.handleClose(ModalState.Ok);
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
className={Classes.INTENT_DANGER}
|
||||
text="取消"
|
||||
onClick={() => { this.handleClose(ModalState.Cancel); }}
|
||||
/>
|
||||
</ModalFooter>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
private handleClose = (modalState: ModalState) =>
|
||||
{
|
||||
if (this.props.selectDiv)
|
||||
this.props.selectDiv.style.visibility = Visibility.Hidden;
|
||||
else
|
||||
{
|
||||
app.Editor.ModalManage.m_PromisRes({ Status: modalState });
|
||||
app.Editor.ModalManage.Destory();
|
||||
}
|
||||
};
|
||||
|
||||
private applySelectTemp()
|
||||
{
|
||||
switch (this.props.location?.get())
|
||||
{
|
||||
case Location.Middle:
|
||||
this.props.store.currentDoorWindowsInfo = {
|
||||
temp: {
|
||||
name: "",
|
||||
id: this.props.store.selectTemplateInfo.temp.id,
|
||||
logo: this.props.store.selectTemplateInfo.temp.logo
|
||||
}
|
||||
};
|
||||
break;
|
||||
case Location.Left:
|
||||
this.props.store.currentLeftBayWindowsInfo = {
|
||||
temp: {
|
||||
name: "",
|
||||
id: this.props.store.selectTemplateInfo.temp.id,
|
||||
logo: this.props.store.selectTemplateInfo.temp.logo
|
||||
}
|
||||
};
|
||||
break;
|
||||
case Location.Right:
|
||||
this.props.store.currentRightBayWindowsInfo = {
|
||||
temp: {
|
||||
name: "",
|
||||
|
||||
id: this.props.store.selectTemplateInfo.temp.id,
|
||||
logo: this.props.store.selectTemplateInfo.temp.logo
|
||||
}
|
||||
};
|
||||
break;
|
||||
case Location.All:
|
||||
this.props.store.currentDoorWindowsInfo = {
|
||||
temp: {
|
||||
name: "",
|
||||
id: this.props.store.selectTemplateInfo.temp.id,
|
||||
logo: this.props.store.selectTemplateInfo.temp.logo
|
||||
}
|
||||
};
|
||||
this.props.store.currentLeftBayWindowsInfo = {
|
||||
temp: {
|
||||
name: "",
|
||||
id: this.props.store.selectTemplateInfo.temp.id,
|
||||
logo: this.props.store.selectTemplateInfo.temp.logo
|
||||
}
|
||||
};
|
||||
this.props.store.currentRightBayWindowsInfo = {
|
||||
temp: {
|
||||
name: "",
|
||||
id: this.props.store.selectTemplateInfo.temp.id,
|
||||
logo: this.props.store.selectTemplateInfo.temp.logo
|
||||
}
|
||||
};
|
||||
break;
|
||||
default:
|
||||
this.props.store.currentDoorWindowsInfo = {
|
||||
temp: {
|
||||
name: "",
|
||||
id: this.props.store.selectTemplateInfo.temp.id,
|
||||
logo: this.props.store.selectTemplateInfo.temp.logo
|
||||
}
|
||||
};
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
import { Matrix4, Vector3 } from "three";
|
||||
import { Factory } from "../../CADFactory";
|
||||
import { CADFiler } from "../../CADFiler";
|
||||
import { Positioning } from "./Positioning";
|
||||
|
||||
@Factory
|
||||
export class PositioningFixed extends Positioning
|
||||
{
|
||||
override async Positioning()
|
||||
{
|
||||
}
|
||||
|
||||
//#region File
|
||||
ReadFile(file: CADFiler): void
|
||||
{
|
||||
let ver = file.Read();
|
||||
|
||||
if (!this.SpaceCS) this.SpaceCS = new Matrix4;
|
||||
if (!this.SpaceSize) this.SpaceSize = new Vector3;
|
||||
|
||||
for (let i = 0; i < 16; i++)
|
||||
this.SpaceCS.elements[i] = file.Read();
|
||||
|
||||
this.SpaceSize.set(file.Read(), file.Read(), file.Read());
|
||||
}
|
||||
|
||||
WriteFile(file: CADFiler): void
|
||||
{
|
||||
file.Write(1);
|
||||
|
||||
for (let e of this.SpaceCS.elements)
|
||||
file.Write(e);
|
||||
file.Write(this.SpaceSize.x);
|
||||
file.Write(this.SpaceSize.y);
|
||||
file.Write(this.SpaceSize.z);
|
||||
}
|
||||
//#endregion
|
||||
}
|
@ -0,0 +1,280 @@
|
||||
import { MathUtils, Matrix4, Vector3 } from "three";
|
||||
import { app } from "../../../ApplicationServices/Application";
|
||||
import { equaln, ZAxis } from "../../../Geometry/GeUtils";
|
||||
import { BoardType } from "../../../UI/Store/BoardInterface";
|
||||
import { AutoRecord } from "../../AutoRecord";
|
||||
import { Factory } from "../../CADFactory";
|
||||
import { CADFiler } from "../../CADFiler";
|
||||
import { CADObject } from "../../CADObject";
|
||||
import { Arc } from "../../Entity/Arc";
|
||||
import { Board } from "../../Entity/Board";
|
||||
import { Line } from "../../Entity/Line";
|
||||
import { Polyline } from "../../Entity/Polyline";
|
||||
import { HardwareCompositeEntity } from "../../Hardware/HardwareCompositeEntity";
|
||||
import { DefaultParamMap, SetMaterialParams } from "../../IMaterialDefaultParam";
|
||||
import { ObjectId } from "../../ObjectId";
|
||||
import { PhysicalMaterialRecord } from "../../PhysicalMaterialRecord";
|
||||
import { RoomHolePolyline } from "../../Room/Entity/Wall/Hole/RoomHolePolyline";
|
||||
import { RoomWallArc } from "../../Room/Entity/Wall/RoomWallArc";
|
||||
import { TemplateRecord } from "../TemplateRecord";
|
||||
|
||||
/**
|
||||
* 弧形窗
|
||||
*/
|
||||
@Factory
|
||||
export class TemplateArcWindowRecord extends TemplateRecord
|
||||
{
|
||||
constructor()
|
||||
{
|
||||
super();
|
||||
this.name = "弧形窗(自动)";
|
||||
}
|
||||
|
||||
@AutoRecord HoleObjectId: ObjectId<RoomHolePolyline>;
|
||||
@AutoRecord ArcWallIndex: number;
|
||||
|
||||
InitWindowFrame(hole: RoomHolePolyline, arcWallIndex: number)
|
||||
{
|
||||
if (!hole.objectId) return;
|
||||
this.HoleObjectId = hole.objectId;
|
||||
this.ArcWallIndex = arcWallIndex;
|
||||
|
||||
//下边框
|
||||
let bottomFrame = Board.CreateBoard(50, 50, 50, BoardType.Layer);
|
||||
bottomFrame.ApplyMatrix(bottomFrame.OCSInv);
|
||||
bottomFrame.ColorIndex = 8;
|
||||
|
||||
//玻璃
|
||||
let glass = bottomFrame.Clone();
|
||||
glass.ColorIndex = 7;
|
||||
|
||||
//其余边框
|
||||
let leftFrame = bottomFrame.Clone();
|
||||
|
||||
let rightFrame = bottomFrame.Clone();
|
||||
|
||||
let topFrame = bottomFrame.Clone();
|
||||
|
||||
let windowModel = new HardwareCompositeEntity();
|
||||
windowModel.Entitys.push(leftFrame, rightFrame, topFrame, bottomFrame, glass);
|
||||
app.Database.ModelSpace.Append(windowModel);
|
||||
this.Objects.push(windowModel.Id);
|
||||
|
||||
//边框材质
|
||||
let frameMaterial = app.Database.MaterialTable.GetAt("弧形窗边框");
|
||||
if (!frameMaterial)
|
||||
{
|
||||
frameMaterial = new PhysicalMaterialRecord();
|
||||
SetMaterialParams(frameMaterial, DefaultParamMap.金属);
|
||||
frameMaterial.Name = "弧形窗边框";
|
||||
frameMaterial.type = "金属";
|
||||
frameMaterial.color = "#333333";
|
||||
frameMaterial.roughness = 0.4;//粗糙度
|
||||
frameMaterial.specular = 0.5;//高光
|
||||
frameMaterial.Update();
|
||||
app.Database.MaterialTable.Add(frameMaterial);
|
||||
}
|
||||
windowModel.Material = frameMaterial.Id;
|
||||
|
||||
//玻璃材质
|
||||
let glassMaterial = app.Database.MaterialTable.GetAt("弧形窗玻璃");
|
||||
if (!glassMaterial)
|
||||
{
|
||||
glassMaterial = new PhysicalMaterialRecord();
|
||||
SetMaterialParams(glassMaterial, DefaultParamMap.玻璃);
|
||||
glassMaterial.Name = "弧形窗玻璃";
|
||||
glassMaterial.type = "玻璃";
|
||||
glassMaterial.transparent = true;
|
||||
glassMaterial.opacity = 0.4;
|
||||
glassMaterial.Update();
|
||||
app.Database.MaterialTable.Add(glassMaterial);
|
||||
}
|
||||
glass.Material = glassMaterial.Id;
|
||||
}
|
||||
|
||||
protected async Update()
|
||||
{
|
||||
await super.Update();
|
||||
let [windowModelId] = this.Objects;
|
||||
if (!windowModelId || windowModelId.IsErase) return;
|
||||
|
||||
let hole = this.HoleObjectId?.Object;
|
||||
let arcWall = hole?.FakerWalls[this.ArcWallIndex] as RoomWallArc;
|
||||
|
||||
if (!hole || !arcWall) return;
|
||||
|
||||
let windowModel = windowModelId.Object as HardwareCompositeEntity;
|
||||
|
||||
let leftFrame = windowModel.Entitys[0] as Board;
|
||||
let rightFrame = windowModel.Entitys[1] as Board;
|
||||
let topFrame = windowModel.Entitys[2] as Board;
|
||||
let bottomFrame = windowModel.Entitys[3] as Board;
|
||||
let glass = windowModel.Entitys[4] as Board;
|
||||
|
||||
bottomFrame.ApplyMatrix(bottomFrame.OCSInv);
|
||||
|
||||
let wpdist = hole.WpDist[0] !== 0 ? hole.WpDist[0] + arcWall.Thickness / 2 + 25 : 0;//外飘时考虑 墙厚 + 边框厚 + 外飘距离
|
||||
|
||||
const radius = arcWall.Radius;
|
||||
let leftArc = arcWall.LeftCurves[0] as Arc;
|
||||
let rightArc = arcWall.RightCurves[0] as Arc;
|
||||
|
||||
//弧形窗角度
|
||||
let allAngle = arcWall.AllAngle;
|
||||
let midAngle = allAngle / 2;
|
||||
let midDistance = (leftArc.EndPoint.distanceTo(leftArc.StartPoint) + rightArc.EndPoint.distanceTo(rightArc.StartPoint)) / 4;
|
||||
|
||||
let maxThanPI = allAngle > Math.PI;
|
||||
|
||||
//弧形圆点
|
||||
let center: Vector3;
|
||||
if (equaln(allAngle, Math.PI, 1e-7))
|
||||
center = new Vector3(radius);
|
||||
else if (allAngle < Math.PI)
|
||||
center = new Vector3(midDistance, - Math.sqrt(radius * radius - midDistance * midDistance));
|
||||
else if (maxThanPI) //弧形大于Π时,会翻转
|
||||
{
|
||||
let radian = 2 * Math.PI / 360 * MathUtils.radToDeg(Math.PI - midAngle);
|
||||
center = new Vector3(radius + wpdist, Math.cos(radian) * (radius + wpdist));
|
||||
}
|
||||
|
||||
// let reduceAngle = MathUtils.degToRad(25 * 180 / (Math.PI * radius));
|
||||
|
||||
let startAngle = Math.PI / 2 + midAngle;
|
||||
let endAngle = Math.PI / 2 - midAngle;
|
||||
|
||||
//内缩
|
||||
// if (hole.FakerWalls.length === 2)
|
||||
// {
|
||||
// if (equalv3(arcWall.StartPoint.clone().applyMatrix4(hole.OCSInv), new Vector3(0)))
|
||||
// startAngle = startAngle + reduceAngle * (maxThanPI ? 1 : -1);
|
||||
// else
|
||||
// endAngle = endAngle + reduceAngle * (maxThanPI ? -1 : 1);;
|
||||
// }
|
||||
|
||||
//下边框弧形轮廓
|
||||
let bottomArc1 = new Arc(center, radius - 25 + wpdist, startAngle, endAngle);
|
||||
let bottomArc2 = new Arc(center, radius + 25 + wpdist, startAngle, endAngle);
|
||||
let bottomCloseLine1 = new Line(bottomArc1.StartPoint, bottomArc2.StartPoint);
|
||||
let bottomCloseLine2 = new Line(bottomArc1.EndPoint, bottomArc2.EndPoint);
|
||||
let bottomContourCurve = Polyline.Combine([bottomArc1, bottomCloseLine1, bottomArc2, bottomCloseLine2]);
|
||||
bottomFrame.ContourCurve = bottomContourCurve;
|
||||
|
||||
//玻璃弧长50 的角度
|
||||
let glassAngle1 = MathUtils.degToRad(50 * 180 / (Math.PI * (radius - 2)));
|
||||
let glassAngle2 = MathUtils.degToRad(50 * 180 / (Math.PI * (radius + 2)));
|
||||
|
||||
//玻璃
|
||||
let glassArc1 = new Arc(center, radius - 2 + wpdist, startAngle - glassAngle1, endAngle + glassAngle1);
|
||||
let glassArc2 = new Arc(center, radius + 2 + wpdist, startAngle - glassAngle2, endAngle + glassAngle2);
|
||||
let glassCloseLine1 = new Line(glassArc1.StartPoint, glassArc2.StartPoint);
|
||||
let glassCloseLine2 = new Line(glassArc1.EndPoint, glassArc2.EndPoint);
|
||||
let glassContourCurve = Polyline.Combine([glassArc1, glassCloseLine1, glassArc2, glassCloseLine2]);
|
||||
|
||||
glass.Thickness = hole.Height - 100;
|
||||
glass.ApplyMatrix(glass.OCSInv);
|
||||
|
||||
glass.ContourCurve = glassContourCurve;
|
||||
glass.Position = glass.Position.add(new Vector3(0, 0, 50));
|
||||
|
||||
//上边框
|
||||
topFrame.CopyFrom(bottomFrame);
|
||||
topFrame.Position = bottomFrame.Position.add(new Vector3(0, 0, hole.Height - 50));
|
||||
|
||||
//边框弧长50 的角度
|
||||
let angle1 = MathUtils.degToRad(50 * 180 / (Math.PI * (radius - 25)));
|
||||
let angle2 = MathUtils.degToRad(50 * 180 / (Math.PI * (radius + 25)));
|
||||
|
||||
//左边框弧形轮廓
|
||||
let leftArc1 = bottomArc1.Clone();
|
||||
let leftArc2 = bottomArc2.Clone();
|
||||
if (maxThanPI)
|
||||
{
|
||||
leftArc1.StartAngle = leftArc1.EndAngle + angle1;
|
||||
leftArc2.StartAngle = leftArc2.EndAngle + angle2;
|
||||
}
|
||||
else
|
||||
{
|
||||
leftArc1.EndAngle = leftArc1.StartAngle - angle1;
|
||||
leftArc2.EndAngle = leftArc2.StartAngle - angle2;
|
||||
}
|
||||
|
||||
let leftCloseLine1 = new Line(leftArc1.StartPoint, leftArc2.StartPoint);
|
||||
let leftCloseLine2 = new Line(leftArc1.EndPoint, leftArc2.EndPoint);
|
||||
let leftFrameContourCurve = Polyline.Combine([leftArc1, leftCloseLine1, leftArc2, leftCloseLine2]);
|
||||
|
||||
leftFrame.Thickness = hole.Height - 100;
|
||||
leftFrame.ApplyMatrix(leftFrame.OCSInv);
|
||||
|
||||
leftFrame.ContourCurve = leftFrameContourCurve;
|
||||
leftFrame.Position = leftFrame.Position.add(new Vector3(0, 0, 50));
|
||||
|
||||
//右边框弧形轮廓
|
||||
let rightArc1 = bottomArc1.Clone();
|
||||
let rightArc2 = bottomArc2.Clone();
|
||||
if (maxThanPI)
|
||||
{
|
||||
rightArc1.EndAngle = rightArc1.StartAngle - angle1;
|
||||
rightArc2.EndAngle = rightArc2.StartAngle - angle2;
|
||||
}
|
||||
else
|
||||
{
|
||||
rightArc1.StartAngle = rightArc1.EndAngle + angle1;
|
||||
rightArc2.StartAngle = rightArc2.EndAngle + angle2;
|
||||
}
|
||||
let rightCloseLine1 = new Line(rightArc1.StartPoint, rightArc2.StartPoint);
|
||||
let rightCloseLine2 = new Line(rightArc1.EndPoint, rightArc2.EndPoint);
|
||||
let rightFrameContourCurve = Polyline.Combine([rightArc1, rightCloseLine1, rightArc2, rightCloseLine2]);
|
||||
|
||||
rightFrame.Thickness = hole.Height - 100;
|
||||
rightFrame.ApplyMatrix(rightFrame.OCSInv);
|
||||
|
||||
rightFrame.ContourCurve = rightFrameContourCurve;
|
||||
rightFrame.Position = rightFrame.Position.add(new Vector3(0, 0, 50));
|
||||
|
||||
//定位
|
||||
let pos = arcWall.IsClockWise ? arcWall.StartPoint.clone() : arcWall.EndPoint.clone();
|
||||
let x = arcWall.EndPoint.sub(arcWall.StartPoint).normalize().multiplyScalar(arcWall.IsClockWise ? 1 : -1);
|
||||
let z = ZAxis;
|
||||
let y = new Vector3().crossVectors(ZAxis, x);
|
||||
|
||||
if (maxThanPI)
|
||||
{
|
||||
//外飘时基点外移
|
||||
let v = arcWall.Center.clone().sub(pos).normalize();
|
||||
pos.subVectors(pos, v.multiplyScalar(wpdist));
|
||||
|
||||
//边框处在第一象限
|
||||
let scalar = (rightArc1.StartPoint.x + rightArc2.StartPoint.x) / 2;
|
||||
pos.subVectors(pos, x.clone().multiplyScalar(scalar));
|
||||
}
|
||||
|
||||
windowModel.OCS = new Matrix4().makeBasis(x, y, z).setPosition(pos);
|
||||
windowModel.Update();
|
||||
}
|
||||
|
||||
//#region -------------------------File-------------------------
|
||||
//对象从文件中读取数据,初始化自身
|
||||
override ReadFile(file: CADFiler)
|
||||
{
|
||||
let ver = file.Read();
|
||||
super.ReadFile(file);
|
||||
this.HoleObjectId = file.ReadObjectId() as any;
|
||||
this.ArcWallIndex = file.Read();
|
||||
}
|
||||
//对象将自身数据写入到文件.
|
||||
override WriteFile(file: CADFiler)
|
||||
{
|
||||
file.Write(1);
|
||||
super.WriteFile(file);
|
||||
file.WriteObjectId(this.HoleObjectId);
|
||||
file.Write(this.ArcWallIndex);
|
||||
}
|
||||
|
||||
//局部撤销
|
||||
override ApplyPartialUndo(undoData: CADObject)
|
||||
{
|
||||
super.ApplyPartialUndo(undoData);
|
||||
}
|
||||
//#endregion
|
||||
}
|
@ -0,0 +1,93 @@
|
||||
import { Vector3 } from "three";
|
||||
import { AutoRecord } from "../../AutoRecord";
|
||||
import { Factory } from "../../CADFactory";
|
||||
import { CADFiler } from "../../CADFiler";
|
||||
import { CADObject } from "../../CADObject";
|
||||
import { ObjectId } from "../../ObjectId";
|
||||
import { RoomHolePolyline } from "../../Room/Entity/Wall/Hole/RoomHolePolyline";
|
||||
import { PositioningFixed } from "../Positioning/PositioningFixed";
|
||||
import { TemplateRecord } from "../TemplateRecord";
|
||||
|
||||
|
||||
/**
|
||||
* 房门模块建模
|
||||
* 禁止使用板来建模(因为板会被倒角)
|
||||
* 默认左侧为门铰链位置 右边为门把手位置
|
||||
* 需要提供门开启旋转轴(门铰链所在的位置)
|
||||
* 移动门外开时门位置的移动动作 所需的移动值?(用于旋转轴的切换?)
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
@Factory
|
||||
export class TemplateRoomDoorRecord extends TemplateRecord
|
||||
{
|
||||
@AutoRecord HoleObjectId: ObjectId<RoomHolePolyline>;
|
||||
@AutoRecord DoorLogo: string;
|
||||
|
||||
constructor()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
InitHoleParams()
|
||||
{
|
||||
let hole = this.HoleObjectId?.Object;
|
||||
if (!hole) return;
|
||||
return this;
|
||||
}
|
||||
|
||||
protected override async Update()
|
||||
{
|
||||
super.Update();
|
||||
|
||||
let hole = this.HoleObjectId?.Object;
|
||||
if (!hole) return;
|
||||
|
||||
if (!this.Children[0]?.Object) return;
|
||||
|
||||
let tr = this.Children[0].Object as TemplateRecord;
|
||||
|
||||
let pos = new PositioningFixed;
|
||||
pos.SpaceCS = hole.FakerWalls[0].OCS;
|
||||
let yDir = new Vector3().setFromMatrixColumn(pos.SpaceCS, 1);
|
||||
pos.SpaceCS.elements[12] -= yDir.x * hole.FakerWalls[0].Thickness * 0.5;
|
||||
pos.SpaceCS.elements[13] -= yDir.y * hole.FakerWalls[0].Thickness * 0.5;
|
||||
pos.SpaceCS.elements[14] -= yDir.z * hole.FakerWalls[0].Thickness * 0.5;
|
||||
|
||||
let wall = hole.FakerWalls[0];
|
||||
pos.SpaceSize = new Vector3(wall.Length, wall.Thickness, wall.Height);
|
||||
tr.Positioning = pos;
|
||||
}
|
||||
|
||||
|
||||
//#region -------------------------File-------------------------
|
||||
//对象从文件中读取数据,初始化自身
|
||||
override ReadFile(file: CADFiler)
|
||||
{
|
||||
let ver = file.Read();
|
||||
super.ReadFile(file);
|
||||
this.HoleObjectId = file.ReadObjectId() as any;
|
||||
|
||||
if (ver > 1)
|
||||
{
|
||||
this.DoorLogo = file.Read();
|
||||
}
|
||||
}
|
||||
//对象将自身数据写入到文件.
|
||||
override WriteFile(file: CADFiler)
|
||||
{
|
||||
file.Write(2);
|
||||
super.WriteFile(file);
|
||||
file.WriteObjectId(this.HoleObjectId);
|
||||
|
||||
file.Write(this.DoorLogo);
|
||||
}
|
||||
|
||||
//局部撤销
|
||||
override ApplyPartialUndo(undoData: CADObject)
|
||||
{
|
||||
super.ApplyPartialUndo(undoData);
|
||||
}
|
||||
//#endregion
|
||||
}
|
@ -0,0 +1,394 @@
|
||||
import { Matrix4, Vector3 } from "three";
|
||||
import { arrayLast } from "../../../Common/ArrayExt";
|
||||
import { EntityUpdateWrap } from "../../../Common/EntityUpdateWrap";
|
||||
import { ZAxis } from "../../../Geometry/GeUtils";
|
||||
import { IntersectOption } from "../../../GraphicsSystem/IntersectWith";
|
||||
import { AutoRecord } from "../../AutoRecord";
|
||||
import { Factory } from "../../CADFactory";
|
||||
import { CADFiler } from "../../CADFiler";
|
||||
import { CADObject } from "../../CADObject";
|
||||
import { Curve } from "../../Entity/Curve";
|
||||
import { ObjectId } from "../../ObjectId";
|
||||
import { RoomHolePolyline } from "../../Room/Entity/Wall/Hole/RoomHolePolyline";
|
||||
import { RoomWallArc } from "../../Room/Entity/Wall/RoomWallArc";
|
||||
import { RoomWallLine } from "../../Room/Entity/Wall/RoomWallLine";
|
||||
import { TemplateParam } from "../Param/TemplateParam";
|
||||
import { PositioningFixed } from "../Positioning/PositioningFixed";
|
||||
import { TemplateRecord } from "../TemplateRecord";
|
||||
|
||||
|
||||
/**
|
||||
* 窗:
|
||||
* I(窗)
|
||||
* L(转角窗,2面墙,4面飘窗) (左边墙?) (右边墙?) (左边窗?)
|
||||
* U(转角窗,2面墙,6面飘窗) (左边墙?) (右边墙?)
|
||||
*
|
||||
* 对于这种转角窗 需要生成一个V型的实体来补一下
|
||||
*
|
||||
* 圆弧窗?
|
||||
*
|
||||
* 参数:
|
||||
*
|
||||
* 窗框材质
|
||||
*
|
||||
* 窗台石? 台面厚度? 台面凸出? 台面左右凸出
|
||||
*
|
||||
* I 外飘 = W/2 居中
|
||||
* L 左外飘 右外飘
|
||||
* U 左外飘 中外飘 右外飘?
|
||||
*/
|
||||
|
||||
//窗台石默认参数
|
||||
const DefaultCTSarams: [string, string, string][] = [
|
||||
["CTS", "窗台石?", "1"],
|
||||
["CTSH", "窗石厚", "30"],
|
||||
["CTSTC", "窗石凸", "30"],
|
||||
["CTSZYTC", "左右凸出", "30"],
|
||||
["WZ", "窗位置", "25"],//在外飘未启用之前
|
||||
["HD", "窗厚度", "50"],//在外飘未启用之前
|
||||
];
|
||||
|
||||
const DefaultIWindowParams: [string, string, string][] = [
|
||||
["WP", "外飘", "500"],
|
||||
];
|
||||
|
||||
const DefaultLWindowParams: [string, string, string][] = [
|
||||
["ZWP", "左外飘", "500"],
|
||||
["YWP", "右外飘", "500"],
|
||||
];
|
||||
|
||||
const DefaultUWindowParams: [string, string, string][] = [
|
||||
["ZWP", "左外飘", "500"],
|
||||
["MWP", "中外飘", "500"],
|
||||
["YWP", "右外飘", "500"],
|
||||
];
|
||||
|
||||
function InitParam(tr: TemplateRecord, paramD: [string, string, string])
|
||||
{
|
||||
let [name, description, expr] = paramD;
|
||||
let param = tr.GetParam(name);
|
||||
if (param) return;
|
||||
|
||||
param = new TemplateParam();
|
||||
param.name = name;
|
||||
param.expr = expr;
|
||||
param.value = 0;
|
||||
param.description = description;
|
||||
tr.Params.push(param);
|
||||
}
|
||||
|
||||
|
||||
@Factory
|
||||
export class TemplateWindowRecord extends TemplateRecord
|
||||
{
|
||||
@AutoRecord HoleObjectId: ObjectId<RoomHolePolyline>;
|
||||
|
||||
@AutoRecord CTSId: ObjectId;//窗台石id
|
||||
@AutoRecord LeftIsWall = false;
|
||||
@AutoRecord RightIsWall = false;
|
||||
|
||||
@AutoRecord WindowLogo: string;
|
||||
@AutoRecord LeftWindowLogo: string;
|
||||
@AutoRecord RightWindowLogo: string;
|
||||
|
||||
@AutoRecord LeftWindowTemplateId: string;//飘窗左侧窗
|
||||
@AutoRecord RightWindowTemplateId: string;//飘窗右侧窗
|
||||
|
||||
constructor()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
InitHoleParams()
|
||||
{
|
||||
let hole = this.HoleObjectId?.Object;
|
||||
if (!hole) return;
|
||||
|
||||
//初始化窗台石参数
|
||||
for (let p of DefaultCTSarams) InitParam(this, p);
|
||||
|
||||
let holePtsCount = hole.PointsCount;
|
||||
if (holePtsCount === 2)
|
||||
{
|
||||
for (let p of DefaultIWindowParams) InitParam(this, p);
|
||||
}
|
||||
else if (holePtsCount === 3)
|
||||
{
|
||||
for (let p of DefaultLWindowParams) InitParam(this, p);
|
||||
}
|
||||
else if (holePtsCount === 4)
|
||||
{
|
||||
for (let p of DefaultUWindowParams) InitParam(this, p);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
set WpDist(v: number[])
|
||||
{
|
||||
let count = this.HoleObjectId?.Object?.PointsCount;
|
||||
if (!count) return;
|
||||
|
||||
if (count === 2)
|
||||
this.GetParam("WP").expr = v[0];
|
||||
else if (count === 3)
|
||||
{
|
||||
this.GetParam("ZWP").expr = v[0];
|
||||
this.GetParam("YWP").expr = v[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
this.GetParam("ZWP").expr = v[0];
|
||||
this.GetParam("MWP").expr = v[1];
|
||||
this.GetParam("YWP").expr = v[2];
|
||||
}
|
||||
}
|
||||
|
||||
get WpDists(): number[]
|
||||
{
|
||||
let hole = this.HoleObjectId?.Object;
|
||||
if (!hole) return;
|
||||
|
||||
let wpdists: number[] = [];
|
||||
|
||||
let walls = hole.FakerWalls;
|
||||
if (walls.length === 1)
|
||||
{
|
||||
let wp = this.GetParam("WP").value as number;
|
||||
wpdists.push(wp);
|
||||
}
|
||||
else if (walls.length === 2)
|
||||
{
|
||||
let zwp = this.GetParam("ZWP").value as number;
|
||||
let ywp = this.GetParam("YWP").value as number;
|
||||
|
||||
wpdists.push(zwp, ywp);
|
||||
}
|
||||
else if (walls.length === 3)
|
||||
{
|
||||
let zwp = this.GetParam("ZWP").value as number;
|
||||
let mwp = this.GetParam("MWP").value as number;
|
||||
let ywp = this.GetParam("YWP").value as number;
|
||||
|
||||
wpdists.push(zwp, mwp, ywp);
|
||||
}
|
||||
return wpdists;
|
||||
}
|
||||
|
||||
protected override async Update()
|
||||
{
|
||||
super.Update();
|
||||
|
||||
let hole = this.HoleObjectId?.Object;
|
||||
if (!hole) return;
|
||||
|
||||
let ctsParam = this.GetParam("CTS");
|
||||
|
||||
//#region 计算窗台石轮廓
|
||||
let ctstc = this.GetParam("CTSTC").value as number;//窗台石凸出
|
||||
let ctszytc = this.GetParam("CTSZYTC").value as number;//窗台石左右凸出
|
||||
|
||||
let wpdists = this.WpDists;
|
||||
|
||||
let polyline = hole.GetWpRegion(wpdists, ctstc, ctszytc);
|
||||
if (ctsParam.value)//1 使用窗台石?
|
||||
{
|
||||
// Draw(polyline);
|
||||
}
|
||||
|
||||
EntityUpdateWrap(hole, () =>
|
||||
{
|
||||
hole.WpDist = wpdists;
|
||||
hole.WpLeftWall = this.LeftIsWall;
|
||||
hole.WpRightWall = this.RightIsWall;
|
||||
});
|
||||
|
||||
if (wpdists.every(d => d === 0))//没有外飘
|
||||
{
|
||||
let wzParam = this.GetParam("WZ");
|
||||
|
||||
let fakerWalls = hole.FakerWalls;
|
||||
if (wzParam.value !== 0)
|
||||
{
|
||||
fakerWalls = fakerWalls.map(w => w.GetOffsetCurves(wzParam.value as number)[0] as any);
|
||||
|
||||
//窗户相交最近点
|
||||
const getMinDistPoint = (pts: Vector3[], curve: Vector3) =>
|
||||
{
|
||||
let pt: Vector3 = pts[0];
|
||||
let length = curve.distanceTo(pt);
|
||||
for (let y = 1; y < pts.length; y++)
|
||||
{
|
||||
if (curve.distanceTo(pts[y]) < length)
|
||||
pt = pts[y];
|
||||
}
|
||||
return pt;
|
||||
};
|
||||
|
||||
for (let i = 0; i < fakerWalls.length - 1; i++)
|
||||
{
|
||||
let pre = fakerWalls[i];
|
||||
let next = fakerWalls[i + 1];
|
||||
let pt = getMinDistPoint(pre.IntersectWith(next, IntersectOption.ExtendBoth), pre.EndPoint);
|
||||
|
||||
pre.EndPoint = pt;
|
||||
next.StartPoint = pt;
|
||||
}
|
||||
|
||||
for (let w of fakerWalls)
|
||||
{
|
||||
if (w instanceof RoomWallLine)
|
||||
w.UpdateOCSToMinBox();
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < this.Children.length; i++)
|
||||
{
|
||||
if (i > hole.PointsCount) break;
|
||||
|
||||
let wall = fakerWalls[i];
|
||||
|
||||
let ctemplate = this.Children[i].Object as TemplateRecord;
|
||||
|
||||
if (!ctemplate) continue;
|
||||
|
||||
let pos = new PositioningFixed;
|
||||
pos.SpaceCS = wall.OCS;
|
||||
pos.SpaceSize = new Vector3(wall.Length, ctemplate.WParam.value as number, wall.Height);
|
||||
ctemplate.Positioning = pos;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//根据外飘偏移
|
||||
let wpCurves: Curve[] = [];
|
||||
for (let i = 0; i < hole.FakerWalls.length; i++)
|
||||
{
|
||||
let w = hole.FakerWalls[i] as (RoomWallLine | RoomWallArc);
|
||||
let d = wpdists[i];//外飘距离
|
||||
if (w instanceof RoomWallArc)
|
||||
wpCurves.push(w.GetOffsetCurves((w.Thickness * 0.5 + d) * (w.IsClockWise ? -1 : 1))[0]);
|
||||
else
|
||||
wpCurves.push(w.GetOffsetCurves(-(w.Thickness * 0.5 + d))[0]);
|
||||
}
|
||||
//求交连接
|
||||
for (let i = 1; i < wpCurves.length; i++)
|
||||
{
|
||||
let pre = wpCurves[i - 1];
|
||||
let now = wpCurves[i];
|
||||
let iPt = pre.IntersectWith(now, IntersectOption.ExtendBoth)[0];
|
||||
pre.EndPoint = iPt;
|
||||
now.StartPoint = iPt;
|
||||
}
|
||||
|
||||
//左侧非墙
|
||||
let templateIndex = 0;
|
||||
if (!this.LeftIsWall)
|
||||
{
|
||||
templateIndex++;
|
||||
|
||||
let sp = hole.LidCurves[0].StartPoint.setZ(hole.Z);
|
||||
let x = hole.LidCurves[0].GetFistDeriv(0).normalize().negate();
|
||||
let z = ZAxis;
|
||||
let y = new Vector3().crossVectors(ZAxis, x);
|
||||
|
||||
let tr = this.Children[0].Object as TemplateRecord;
|
||||
if (!tr) return;
|
||||
|
||||
let pos = new PositioningFixed;
|
||||
pos.SpaceCS = new Matrix4().makeBasis(x, y, z).setPosition(sp);
|
||||
pos.SpaceSize = new Vector3(wpdists[0], 50, hole.Height);
|
||||
tr.Positioning = pos;
|
||||
}
|
||||
|
||||
for (let i = 0; i < wpCurves.length; i++)
|
||||
{
|
||||
let c = wpCurves[i];
|
||||
let tr = this.Children[templateIndex]?.Object as TemplateRecord;
|
||||
if (!tr) return;
|
||||
|
||||
let sp = c.StartPoint;
|
||||
let x = c.GetFistDeriv(0).normalize();
|
||||
let z = ZAxis;
|
||||
let y = new Vector3().crossVectors(ZAxis, x);
|
||||
|
||||
let pos = new PositioningFixed;
|
||||
pos.SpaceCS = new Matrix4().makeBasis(x, y, z).setPosition(sp);
|
||||
pos.SpaceSize = new Vector3(c.Length, 50, hole.Height);
|
||||
tr.Positioning = pos;
|
||||
|
||||
templateIndex++;
|
||||
}
|
||||
|
||||
if (!this.RightIsWall && arrayLast(wpdists) > 0)
|
||||
{
|
||||
let tr = this.Children[templateIndex]?.Object as TemplateRecord;
|
||||
if (!tr) return;
|
||||
|
||||
let sp = arrayLast(wpCurves).EndPoint;
|
||||
let w = arrayLast(hole.FakerWalls);
|
||||
let x = w.EndPoint.sub(sp).normalize();
|
||||
let z = ZAxis;
|
||||
let y = new Vector3().crossVectors(ZAxis, x);
|
||||
|
||||
let pos = new PositioningFixed;
|
||||
pos.SpaceCS = new Matrix4().makeBasis(x, y, z).setPosition(sp);
|
||||
pos.SpaceSize = new Vector3(arrayLast(wpdists), 50, hole.Height);
|
||||
tr.Positioning = pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//#region -------------------------File-------------------------
|
||||
//对象从文件中读取数据,初始化自身
|
||||
override ReadFile(file: CADFiler)
|
||||
{
|
||||
let ver = file.Read();
|
||||
super.ReadFile(file);
|
||||
|
||||
if (ver > 1)
|
||||
{
|
||||
let wallFlag = file.Read() as number;
|
||||
this.LeftIsWall = (wallFlag & 1) === 1;
|
||||
this.RightIsWall = (wallFlag & 2) === 2;
|
||||
}
|
||||
if (ver > 2)
|
||||
this.HoleObjectId = file.ReadObjectId() as any;
|
||||
|
||||
if (ver > 3)
|
||||
{
|
||||
this.WindowLogo = file.Read();
|
||||
this.LeftWindowLogo = file.Read();
|
||||
this.RightWindowLogo = file.Read();
|
||||
this.LeftWindowTemplateId = file.Read();
|
||||
this.RightWindowTemplateId = file.Read();
|
||||
}
|
||||
}
|
||||
//对象将自身数据写入到文件.
|
||||
override WriteFile(file: CADFiler)
|
||||
{
|
||||
file.Write(4);
|
||||
super.WriteFile(file);
|
||||
|
||||
let wallFlag = 0;
|
||||
if (this.LeftIsWall) wallFlag = 1;
|
||||
if (this.RightIsWall) wallFlag += 2;
|
||||
|
||||
file.Write(wallFlag);
|
||||
|
||||
file.WriteObjectId(this.HoleObjectId);
|
||||
|
||||
file.Write(this.WindowLogo);
|
||||
file.Write(this.LeftWindowLogo);
|
||||
file.Write(this.RightWindowLogo);
|
||||
file.Write(this.LeftWindowTemplateId);
|
||||
file.Write(this.RightWindowTemplateId);
|
||||
}
|
||||
|
||||
//局部撤销
|
||||
override ApplyPartialUndo(undoData: CADObject)
|
||||
{
|
||||
super.ApplyPartialUndo(undoData);
|
||||
}
|
||||
//#endregion
|
||||
}
|
@ -0,0 +1,246 @@
|
||||
import { Card, ContextMenu, Icon, Intent, Menu, MenuItem } from '@blueprintjs/core';
|
||||
import { observable } from 'mobx';
|
||||
import { observer } from 'mobx-react';
|
||||
import * as React from 'react';
|
||||
import { ITempTagProps, templateTagCommand } from '../../../Add-on/Template/TemplateTagCommand';
|
||||
import { CURRENT_HOST, TemplateUrls } from '../../../Common/HostUrl';
|
||||
import { inflateBase64 } from "../../../Common/inflate";
|
||||
import { MouseKey } from '../../../Common/KeyEnum';
|
||||
import { PostJson, RequestStatus } from '../../../Common/Request';
|
||||
import { TemplateParamsIn } from '../../../Common/SerializeMaterial';
|
||||
import { TemplateParam } from '../../../DatabaseServices/Template/Param/TemplateParam';
|
||||
import { IDrawerDoorTempInfo } from '../../Store/DoorInterface';
|
||||
import { ITemplateParam } from "../../Store/RightPanelStore/ITemplateParam";
|
||||
import { HandleDirComponent } from '../SourceManage/HandleDirComponent';
|
||||
import { Pagination } from '../SourceManage/Pagination';
|
||||
import { IGetRoomInfo } from './GetRoomCabName';
|
||||
import { TemplateDetail } from './TemplateDetail';
|
||||
|
||||
export interface ITemplateTagComProps
|
||||
{
|
||||
currentTag: ITempTagProps;
|
||||
currentTemplateInfo: IDrawerDoorTempInfo;
|
||||
currentProps: ITemplateParam[];
|
||||
cabOption: IGetRoomInfo;
|
||||
insert: (isByBasePt: boolean) => void;
|
||||
}
|
||||
|
||||
@observer
|
||||
export class TemplateTagCom extends React.Component<ITemplateTagComProps> {
|
||||
|
||||
@observable private params: TemplateParam[] = [];
|
||||
@observable private dataList = [];
|
||||
@observable private pageData = {
|
||||
count: 0,
|
||||
currentPage: 1,
|
||||
pageCount: 16,
|
||||
};
|
||||
@observable private currentTag: ITempTagProps = { tagName: "", dirId: "", description: "" };
|
||||
private canInput = observable.box(false);
|
||||
private isDesc = true;
|
||||
async UNSAFE_componentWillMount()
|
||||
{
|
||||
Object.assign(this.currentTag, this.props.currentTag);
|
||||
await this.readTemplateInfo();
|
||||
}
|
||||
public render()
|
||||
{
|
||||
return (
|
||||
<Card tabIndex={-1} className="flex" style={{ height: "100%", outline: "none" }}>
|
||||
<ul className="tag-name-list">
|
||||
{
|
||||
templateTagCommand.TagList.map(tag =>
|
||||
{
|
||||
return (
|
||||
<li className={tag.dirId === this.currentTag?.dirId ? "active" : ""} data-id={tag.tagName} onMouseDown={this.selectTemplateTag} >
|
||||
<Icon icon="tag" />
|
||||
{tag.tagName} | {tag.description}</li>
|
||||
);
|
||||
})
|
||||
}
|
||||
</ul>
|
||||
<div className="tag-list" style={{ overflow: "scroll" }}>
|
||||
{
|
||||
this.dataList.map(d =>
|
||||
{
|
||||
return (
|
||||
<div
|
||||
className={this.props.currentTemplateInfo.id === d.mid ? "active tag-img" : "tag-img"}
|
||||
onClick={() => this.selectTemp(d)}
|
||||
onDoubleClick={() => { if (this.props.insert) this.props.insert(false); }}
|
||||
>
|
||||
<div style={{ height: 0, paddingBottom: "100%", textAlign: "center" }}>
|
||||
<img src={d.logo} style={{ height: "auto", width: "80%" }} alt="" />
|
||||
</div>
|
||||
<p className="data-title">{d.name}</p>
|
||||
</div>
|
||||
);
|
||||
})
|
||||
}
|
||||
{
|
||||
this.pageData.count > this.pageData.pageCount && <Pagination
|
||||
pageData={this.pageData}
|
||||
getImgListFun={this.readTemplateInfo}
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
<TemplateDetail
|
||||
className="tag-temp-detail"
|
||||
updateParams={this.props.currentProps}
|
||||
currentInfo={this.props.currentTemplateInfo}
|
||||
showSelectTemp={false}
|
||||
isUpload={true}
|
||||
disableKeys={undefined}
|
||||
isShowTag={false}
|
||||
params={this.params}
|
||||
isShowDetail={true}
|
||||
/>
|
||||
{
|
||||
this.canInput.get() && <HandleDirComponent
|
||||
defualtValue={this.isDesc ? this.currentTag.description : this.currentTag.tagName}
|
||||
isReset={false}
|
||||
isOpen={this.canInput}
|
||||
title={this.isDesc ? "备注" : "标签名"}
|
||||
handleFunc={this.addTagDesc}
|
||||
/>
|
||||
}
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
private readTemplateInfo = async (pageData?: { curr_page: number; }) =>
|
||||
{
|
||||
if (pageData)
|
||||
this.pageData.currentPage = pageData.curr_page;
|
||||
let data = await PostJson(TemplateUrls.list, { dir_id: this.currentTag.dirId, page_count: this.pageData.pageCount, curr_page: this.pageData.currentPage });
|
||||
if (data.err_code === RequestStatus.Ok && data.modules)
|
||||
{
|
||||
this.pageData.count = Number(data.count);
|
||||
let tempData = data.modules;
|
||||
observable(this.dataList).replace(tempData.map(d =>
|
||||
{
|
||||
return {
|
||||
logo: CURRENT_HOST + "/" + d.logo,
|
||||
mid: d.module_id,
|
||||
name: d.name,
|
||||
props: d.props,
|
||||
};
|
||||
}));
|
||||
|
||||
if (this.dataList.length === 1)
|
||||
{
|
||||
this.selectTemp(this.dataList[0]);
|
||||
}
|
||||
}
|
||||
else
|
||||
this.dataList.length === 0;
|
||||
|
||||
};
|
||||
private selectTemplateTag = async (e: React.MouseEvent<HTMLLIElement>) =>
|
||||
{
|
||||
if (e.button === MouseKey.Right)
|
||||
{
|
||||
this.showContextMenu(e);
|
||||
}
|
||||
|
||||
let tagName = e.currentTarget.getAttribute('data-id');
|
||||
Object.assign(this.currentTag, templateTagCommand.GetTagByName(tagName));
|
||||
await this.readTemplateInfo();
|
||||
};
|
||||
private _propsCache = new Map<string, TemplateParam[]>();
|
||||
private selectTemp(data: { mid: string, name: string, props: string; })
|
||||
{
|
||||
const { mid, name, props } = data;
|
||||
this.props.currentTemplateInfo.id = mid;
|
||||
this.props.currentTemplateInfo.name = name;
|
||||
|
||||
this.props.currentTemplateInfo.isHandle = this.currentTag.description.includes("拉手");
|
||||
this.props.currentTemplateInfo.isHinge = this.currentTag.description.includes("铰链");
|
||||
this.props.currentTemplateInfo.isKuGan = this.currentTag.description.includes("裤杆");
|
||||
|
||||
if (!this.props.cabOption.useCabName)
|
||||
{
|
||||
this.props.cabOption.cabName = data.name;
|
||||
this.props.cabOption.originCabName = data.name;
|
||||
this.props.cabOption.cabIndex = 0;
|
||||
}
|
||||
|
||||
let pars: TemplateParam[];
|
||||
if (this._propsCache.has(props))
|
||||
{
|
||||
pars = this._propsCache.get(props);
|
||||
}
|
||||
else
|
||||
pars = TemplateParamsIn(JSON.parse(inflateBase64(props)));
|
||||
observable(this.params).replace(pars);
|
||||
observable(this.props.currentProps).replace(pars.map(p =>
|
||||
{
|
||||
return {
|
||||
name: p.name,
|
||||
value: p.value,
|
||||
description: p.description,
|
||||
expr: p.expr,
|
||||
};
|
||||
}));
|
||||
}
|
||||
//展示右键菜单
|
||||
private showContextMenu = (e: React.MouseEvent<HTMLElement>) =>
|
||||
{
|
||||
let tagName = e.currentTarget.getAttribute('data-id');
|
||||
ContextMenu.show(
|
||||
<Menu>
|
||||
<MenuItem
|
||||
icon="annotation"
|
||||
text="修改标签"
|
||||
onClick={() =>
|
||||
{
|
||||
this.isDesc = false;
|
||||
this.canInput.set(true);
|
||||
}}
|
||||
/>
|
||||
<MenuItem
|
||||
icon="comment"
|
||||
text="编辑描述"
|
||||
onClick={() =>
|
||||
{
|
||||
this.isDesc = true;
|
||||
this.canInput.set(true);
|
||||
}}
|
||||
/>
|
||||
<MenuItem
|
||||
icon="trash"
|
||||
text="移除标签"
|
||||
intent={Intent.DANGER}
|
||||
onClick={() => this.removeTag(tagName)}
|
||||
/>
|
||||
</Menu>,
|
||||
{ left: e.clientX, top: e.clientY },
|
||||
() => this.setState({ isContextMenuOpen: false }),
|
||||
);
|
||||
this.setState({ isContextMenuOpen: true });
|
||||
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
};
|
||||
private removeTag = (tagName: string) =>
|
||||
{
|
||||
if (confirm("确定移除标签?"))
|
||||
{
|
||||
this.dataList.length = 0;
|
||||
templateTagCommand.RemoveTag(tagName);
|
||||
}
|
||||
};
|
||||
private addTagDesc = (val: string) =>
|
||||
{
|
||||
if (this.isDesc)
|
||||
{
|
||||
templateTagCommand.ModifyTagName(this.currentTag.tagName, undefined, val);
|
||||
this.currentTag.description = val;
|
||||
}
|
||||
else
|
||||
{
|
||||
templateTagCommand.ModifyTagName(this.currentTag.tagName, val.toUpperCase());
|
||||
this.currentTag.tagName = val.toUpperCase();
|
||||
}
|
||||
this.canInput.set(false);
|
||||
};
|
||||
}
|
Loading…
Reference in new issue