From 443a4bda3a4b7fc6152d0ffe1411d51db24942f7 Mon Sep 17 00:00:00 2001 From: fan Date: Thu, 31 Aug 2023 15:52:25 +0800 Subject: [PATCH] customDialog --- .../graphics/CustomDialogInteraction.ts | 40 ++++++++ src/drawApp/graphics/RectInteraction.ts | 75 --------------- src/drawApp/index.ts | 11 +++ src/graphics/customDialog/closeButton.ts | 61 ++++++++++++ src/graphics/customDialog/customDialog.ts | 87 +++++++++++++++++ .../customDialog/customDialogDrawAssistant.ts | 76 +++++++++++++++ src/protos/stationLayoutGraphics.ts | 93 +++++++++++++++++++ 7 files changed, 368 insertions(+), 75 deletions(-) create mode 100644 src/drawApp/graphics/CustomDialogInteraction.ts delete mode 100644 src/drawApp/graphics/RectInteraction.ts create mode 100644 src/graphics/customDialog/closeButton.ts create mode 100644 src/graphics/customDialog/customDialog.ts create mode 100644 src/graphics/customDialog/customDialogDrawAssistant.ts diff --git a/src/drawApp/graphics/CustomDialogInteraction.ts b/src/drawApp/graphics/CustomDialogInteraction.ts new file mode 100644 index 0000000..c3e4928 --- /dev/null +++ b/src/drawApp/graphics/CustomDialogInteraction.ts @@ -0,0 +1,40 @@ +import * as pb_1 from 'google-protobuf'; +import { + CustomDialog, + ICustomDialog, +} from 'src/graphics/customDialog/customDialog'; +import { graphicData } from 'src/protos/stationLayoutGraphics'; +import { GraphicDataBase } from './GraphicDataBase'; + +export class CustomDialogData extends GraphicDataBase implements ICustomDialog { + constructor(data?: graphicData.CustomDialog) { + let gatedBox; + if (!data) { + gatedBox = new graphicData.CustomDialog({ + common: GraphicDataBase.defaultCommonInfo(CustomDialog.Type), + }); + } else { + gatedBox = data; + } + super(gatedBox); + } + + public get data(): graphicData.CustomDialog { + return this.getData(); + } + get code(): string { + return this.data.code; + } + set code(v: string) { + this.data.code = v; + } + clone(): CustomDialogData { + return new CustomDialogData(this.data.cloneMessage()); + } + copyFrom(data: CustomDialogData): void { + pb_1.Message.copyInto(data.data, this.data); + } + eq(other: CustomDialogData): boolean { + return pb_1.Message.equals(this.data, other.data); + } +} diff --git a/src/drawApp/graphics/RectInteraction.ts b/src/drawApp/graphics/RectInteraction.ts deleted file mode 100644 index 3ea0c2e..0000000 --- a/src/drawApp/graphics/RectInteraction.ts +++ /dev/null @@ -1,75 +0,0 @@ -import * as pb_1 from 'google-protobuf'; -import { IPointData } from 'pixi.js'; -import { IRectData, Rect } from 'src/graphics/rect/Rect'; -import { graphicData } from 'src/protos/stationLayoutGraphics'; -import { GraphicDataBase } from './GraphicDataBase'; - -export class RectData extends GraphicDataBase implements IRectData { - constructor(data?: graphicData.Rect) { - let rect; - if (!data) { - rect = new graphicData.Rect({ - common: GraphicDataBase.defaultCommonInfo(Rect.Type), - }); - } else { - rect = data; - } - super(rect); - } - - public get data(): graphicData.Rect { - return this.getData(); - } - - get code(): string { - return this.data.code; - } - set code(v: string) { - this.data.code = v; - } - get lineWidth(): number { - return this.data.lineWidth; - } - set lineWidth(v: number) { - this.data.lineWidth = v; - } - get lineColor(): string { - return this.data.lineColor; - } - set lineColor(v: string) { - this.data.lineColor = v; - } - get point(): IPointData { - return this.data.point; - } - set point(point: IPointData) { - this.data.point = new graphicData.Point({ x: point.x, y: point.y }); - } - get width(): number { - return this.data.width; - } - set width(v: number) { - this.data.width = v; - } - get height(): number { - return this.data.height; - } - set height(v: number) { - this.data.height = v; - } - get radius(): number { - return this.data.radius; - } - set radius(v: number) { - this.data.radius = v; - } - clone(): RectData { - return new RectData(this.data.cloneMessage()); - } - copyFrom(data: RectData): void { - pb_1.Message.copyInto(data.data, this.data); - } - eq(other: RectData): boolean { - return pb_1.Message.equals(this.data, other.data); - } -} diff --git a/src/drawApp/index.ts b/src/drawApp/index.ts index 4d461f9..e47d0f9 100644 --- a/src/drawApp/index.ts +++ b/src/drawApp/index.ts @@ -146,6 +146,12 @@ import { TrackLogicSectionTemplate, } from 'src/graphics/trackLogicSection/TrackLogicSection'; import { TrackLogicSectionData } from './graphics/TrackLogicSectionInteraction'; +import { + CustomDialog, + CustomDialogTemplate, +} from 'src/graphics/customDialog/customDialog'; +import { CustomDialogDraw } from 'src/graphics/customDialog/customDialogDrawAssistant'; +import { CustomDialogData } from './graphics/CustomDialogInteraction'; // export function fromStoragePoint(p: graphicData.Point): Point { // return new Point(p.x, p.y); @@ -276,6 +282,7 @@ export function initDrawApp(dom: HTMLElement): JlDrawApp { | CurvatureDraw | TrackSectionDraw | TrackLogicSectionDraw + | CustomDialogDraw )[] = []; if (draftType === 'Line') { drawAssistants = [ @@ -340,6 +347,10 @@ export function initDrawApp(dom: HTMLElement): JlDrawApp { app, new TrackLogicSectionTemplate(new TrackLogicSectionData()) ), + new CustomDialogDraw( + app, + new CustomDialogTemplate(new CustomDialogData()) + ), ]; DrawSignalInteraction.init(app); DrawStopPositionInteraction.init(app); diff --git a/src/graphics/customDialog/closeButton.ts b/src/graphics/customDialog/closeButton.ts new file mode 100644 index 0000000..98431e4 --- /dev/null +++ b/src/graphics/customDialog/closeButton.ts @@ -0,0 +1,61 @@ +import { Container, Graphics } from 'pixi.js'; + +const closeButtonConsts = { + bodyColor: '0XFF0000', + lineColor: '0XFFFFFF', + lineWidth: 2, + bodyRectWidth: 22, + bodyRectHeight: 22, + rectRadius: 3, + lineHalfLength: 6, +}; + +export class CloseButton extends Container { + static Type = 'closeButton'; + rectBody: Graphics = new Graphics(); + lineBody: Graphics = new Graphics(); + + constructor() { + super(); + this.addChild(this.rectBody); + this.addChild(this.lineBody); + } + + doRepaint() { + this.rectBody.clear(); + this.rectBody.beginFill(closeButtonConsts.bodyColor, 1); + this.rectBody.lineStyle( + closeButtonConsts.lineWidth, + closeButtonConsts.lineColor + ); + this.rectBody.drawRoundedRect( + 0, + 0, + closeButtonConsts.bodyRectWidth, + closeButtonConsts.bodyRectHeight, + closeButtonConsts.rectRadius + ); + this.rectBody.endFill(); + this.lineBody.clear(); + this.lineBody.lineStyle( + closeButtonConsts.lineWidth, + closeButtonConsts.lineColor + ); + this.lineBody.moveTo( + closeButtonConsts.bodyRectWidth / 2 - closeButtonConsts.lineHalfLength, + closeButtonConsts.bodyRectHeight / 2 - closeButtonConsts.lineHalfLength + ); + this.lineBody.lineTo( + closeButtonConsts.bodyRectWidth / 2 + closeButtonConsts.lineHalfLength, + closeButtonConsts.bodyRectHeight / 2 + closeButtonConsts.lineHalfLength + ); + this.lineBody.moveTo( + closeButtonConsts.bodyRectWidth / 2 - closeButtonConsts.lineHalfLength, + closeButtonConsts.bodyRectHeight / 2 + closeButtonConsts.lineHalfLength + ); + this.lineBody.lineTo( + closeButtonConsts.bodyRectWidth / 2 + closeButtonConsts.lineHalfLength, + closeButtonConsts.bodyRectHeight / 2 - closeButtonConsts.lineHalfLength + ); + } +} diff --git a/src/graphics/customDialog/customDialog.ts b/src/graphics/customDialog/customDialog.ts new file mode 100644 index 0000000..8e15ff3 --- /dev/null +++ b/src/graphics/customDialog/customDialog.ts @@ -0,0 +1,87 @@ +import { Graphics } from 'pixi.js'; +import { + GraphicData, + JlGraphic, + JlGraphicTemplate, + VectorText, +} from 'src/jl-graphic'; +import { CloseButton } from './closeButton'; + +export interface ICustomDialog extends GraphicData { + get code(): string; + set code(v: string); + clone(): ICustomDialog; + copyFrom(data: ICustomDialog): void; + eq(other: ICustomDialog): boolean; +} + +const customDialogConsts = { + dialogHeight: 850, + dialogWidth: 600, + innerHeight: 808, + innerWidth: 588, + externalColor: '0X0055E8', + innerFillColor: '0XECE9D8', + innerStrokeColor: '0XB2B1AA', + innerLineWidth: 2, + externalRadius: 5, +}; +export class CustomDialog extends JlGraphic { + static Type = 'customDialog'; + titleGraph: VectorText = new VectorText(''); + externalRect: Graphics = new Graphics(); + innerRect: Graphics = new Graphics(); + closeButton: CloseButton = new CloseButton(); + + constructor() { + super(CustomDialog.Type); + this.addChild(this.titleGraph); + this.addChild(this.externalRect); + this.addChild(this.innerRect); + this.addChild(this.closeButton); + } + get datas(): ICustomDialog { + return this.getDatas(); + } + + doRepaint(): void { + const titleGraph = this.titleGraph; + titleGraph.text = this.datas.code; + this.externalRect.clear(); + this.externalRect.beginFill(customDialogConsts.externalColor, 1); + this.externalRect.drawRoundedRect( + 0, + 0, + customDialogConsts.dialogWidth, + customDialogConsts.dialogHeight, + customDialogConsts.externalRadius + ); + this.externalRect.endFill(); + this.innerRect.clear(); + this.innerRect.beginFill(customDialogConsts.innerFillColor, 1); + this.innerRect.lineStyle( + customDialogConsts.innerLineWidth, + customDialogConsts.innerStrokeColor + ); + this.innerRect.drawRect( + 6, + 35, + customDialogConsts.innerWidth, + customDialogConsts.innerHeight + ); + this.innerRect.endFill(); + this.closeButton.doRepaint(); + this.closeButton.position.set(customDialogConsts.dialogWidth - 28, 6); + } +} + +export class CustomDialogTemplate extends JlGraphicTemplate { + constructor(dataTemplate: ICustomDialog) { + super(CustomDialog.Type, { dataTemplate }); + } + new(): CustomDialog { + const customDialog = new CustomDialog(); + customDialog.loadData(this.datas); + return customDialog; + } +} diff --git a/src/graphics/customDialog/customDialogDrawAssistant.ts b/src/graphics/customDialog/customDialogDrawAssistant.ts new file mode 100644 index 0000000..d0be030 --- /dev/null +++ b/src/graphics/customDialog/customDialogDrawAssistant.ts @@ -0,0 +1,76 @@ +import { FederatedMouseEvent, Point } from 'pixi.js'; +import { + GraphicDrawAssistant, + GraphicInteractionPlugin, + JlDrawApp, + JlGraphic, +} from 'src/jl-graphic'; +import { + CustomDialog, + ICustomDialog, + CustomDialogTemplate, +} from './customDialog'; + +export interface ICustomDialogDrawOptions { + newData: () => ICustomDialog; +} +export class CustomDialogDraw extends GraphicDrawAssistant< + CustomDialogTemplate, + ICustomDialog +> { + _customDialog: CustomDialog | null = null; + constructor(app: JlDrawApp, template: CustomDialogTemplate) { + super(app, template, 'svguse:../../drawIcon.svg#icon-gated-box', '弹窗'); + CustomDialogInteraction.init(app); + } + public get customDialog(): CustomDialog { + if (!this._customDialog) { + this._customDialog = this.graphicTemplate.new(); + this._customDialog.loadData(this.graphicTemplate.datas); + this.container.addChild(this._customDialog); + } + return this._customDialog; + } + + onLeftUp(e: FederatedMouseEvent): void { + this.container.position.copyFrom(this.toCanvasCoordinates(e.global)); + this.createAndStore(true); + } + + redraw(p: Point): void { + this.customDialog.repaint(); + this.container.position.set(p.x, p.y); + } + + prepareData(data: ICustomDialog): boolean { + data.transform = this.container.saveTransform(); + data.code = 'P'; + return true; + } +} + +export class CustomDialogInteraction extends GraphicInteractionPlugin { + static Name = 'gated_box_transform'; + constructor(app: JlDrawApp) { + super(CustomDialogInteraction.Name, app); + } + static init(app: JlDrawApp) { + return new CustomDialogInteraction(app); + } + filter(...grahpics: JlGraphic[]): CustomDialog[] | undefined { + return grahpics + .filter((g) => g.type === CustomDialog.Type) + .map((g) => g as CustomDialog); + } + bind(g: CustomDialog): void { + g.eventMode = 'static'; + g.cursor = 'pointer'; + g.scalable = true; + g.rotatable = true; + } + unbind(g: CustomDialog): void { + g.eventMode = 'none'; + g.scalable = false; + g.rotatable = false; + } +} diff --git a/src/protos/stationLayoutGraphics.ts b/src/protos/stationLayoutGraphics.ts index 10316f3..79a146c 100644 --- a/src/protos/stationLayoutGraphics.ts +++ b/src/protos/stationLayoutGraphics.ts @@ -5977,4 +5977,97 @@ export namespace graphicData { } } } + export class CustomDialog extends pb_1.Message { + #one_of_decls: number[][] = []; + constructor(data?: any[] | { + common?: CommonInfo; + code?: string; + }) { + super(); + pb_1.Message.initialize(this, Array.isArray(data) ? data : [], 0, -1, [], this.#one_of_decls); + if (!Array.isArray(data) && typeof data == "object") { + if ("common" in data && data.common != undefined) { + this.common = data.common; + } + if ("code" in data && data.code != undefined) { + this.code = data.code; + } + } + } + get common() { + return pb_1.Message.getWrapperField(this, CommonInfo, 1) as CommonInfo; + } + set common(value: CommonInfo) { + pb_1.Message.setWrapperField(this, 1, value); + } + get has_common() { + return pb_1.Message.getField(this, 1) != null; + } + get code() { + return pb_1.Message.getFieldWithDefault(this, 2, "") as string; + } + set code(value: string) { + pb_1.Message.setField(this, 2, value); + } + static fromObject(data: { + common?: ReturnType; + code?: string; + }): CustomDialog { + const message = new CustomDialog({}); + if (data.common != null) { + message.common = CommonInfo.fromObject(data.common); + } + if (data.code != null) { + message.code = data.code; + } + return message; + } + toObject() { + const data: { + common?: ReturnType; + code?: string; + } = {}; + if (this.common != null) { + data.common = this.common.toObject(); + } + if (this.code != null) { + data.code = this.code; + } + return data; + } + serialize(): Uint8Array; + serialize(w: pb_1.BinaryWriter): void; + serialize(w?: pb_1.BinaryWriter): Uint8Array | void { + const writer = w || new pb_1.BinaryWriter(); + if (this.has_common) + writer.writeMessage(1, this.common, () => this.common.serialize(writer)); + if (this.code.length) + writer.writeString(2, this.code); + if (!w) + return writer.getResultBuffer(); + } + static deserialize(bytes: Uint8Array | pb_1.BinaryReader): CustomDialog { + const reader = bytes instanceof pb_1.BinaryReader ? bytes : new pb_1.BinaryReader(bytes), message = new CustomDialog(); + while (reader.nextField()) { + if (reader.isEndGroup()) + break; + switch (reader.getFieldNumber()) { + case 1: + reader.readMessage(message.common, () => message.common = CommonInfo.deserialize(reader)); + break; + case 2: + message.code = reader.readString(); + break; + default: reader.skipField(); + } + } + return message; + } + serializeBinary(): Uint8Array { + return this.serialize(); + } + static deserializeBinary(bytes: Uint8Array): CustomDialog { + return CustomDialog.deserialize(bytes); + } + } }