防淹门、车库门、洗车机调整
This commit is contained in:
parent
4314e0db79
commit
dd5f77d6f1
@ -75,4 +75,10 @@
|
||||
<path d="M20 27H39" stroke="#FFFFFF"/>
|
||||
<path d="M29 27V43" stroke="#FFFFFF"/>
|
||||
</symbol>
|
||||
<symbol id="icon-flood-gate" viewBox="0 0 129 139">
|
||||
<path fill-rule="evenodd" stroke="rgba(255, 255, 255, 1)" stroke-width="3" d="M0 1.5L61.5 1.5M61.5 1.5L123 1.5M61.5 1.5L61.5 137.5L0 137.5L123 137.5">
|
||||
</symbol>
|
||||
<symbol id="icon-car-washing" viewBox="0 0 57 57" fill="none">
|
||||
<rect x="1.5" y="8.5" width="47" height="47" stroke="#FFFFFF" fill="none" stroke-width="3"/>
|
||||
</symbol>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 12 KiB |
@ -12,4 +12,4 @@
|
||||
<path fill="#00B4FF"
|
||||
d="M.5 251.9c29.6-.5 59.2-.8 88.8-1l88.7-.3 88.7.3 44.4.4 44.4.6-44.4.6-44.4.4-88.7.3-88.7-.3a7981 7981 0 01-88.8-1z" />
|
||||
<path fill="none" d="M-565.2 324H-252v15.8h-313.2z" />
|
||||
</svg>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 4.4 KiB |
@ -139,6 +139,15 @@
|
||||
drawStore.selectedGraphicType === ConcentrationDividingLine.Type
|
||||
"
|
||||
/>
|
||||
<flood-gate-property
|
||||
v-else-if="drawStore.selectedGraphicType === FloodGate.Type"
|
||||
/>
|
||||
<car-washing-property
|
||||
v-else-if="drawStore.selectedGraphicType === CarWashing.Type"
|
||||
></car-washing-property>
|
||||
<garage-door-property
|
||||
v-else-if="drawStore.selectedGraphicType === GarageDoor.Type"
|
||||
></garage-door-property>
|
||||
</q-card-section>
|
||||
</template>
|
||||
<template v-else-if="drawStore.selectedGraphics.length > 1">
|
||||
@ -217,6 +226,12 @@ import { TrackLogicSection } from 'src/graphics/trackLogicSection/TrackLogicSect
|
||||
import MultipleSelectProperty from './properties/multipleSelectProperty.vue';
|
||||
import { DepartureTimer } from 'src/graphics/departureTimer/DepartureTimer';
|
||||
import DepartureTimerProperty from './properties/DepartureTimerProperty.vue';
|
||||
import FloodGateProperty from './properties/FloodGateProperty.vue';
|
||||
import { FloodGate } from 'src/graphics/floodGate/FloodGate';
|
||||
import GarageDoorProperty from './properties/GarageDoorProperty.vue';
|
||||
import { GarageDoor } from 'src/graphics/garageDoor/GarageDoor';
|
||||
import CarWashingProperty from './properties/CarWashingProperty.vue';
|
||||
import { CarWashing } from 'src/graphics/carWashing/CarWashing';
|
||||
|
||||
const drawStore = useDrawStore();
|
||||
</script>
|
||||
|
100
src/components/draw-app/properties/CarWashingProperty.vue
Normal file
100
src/components/draw-app/properties/CarWashingProperty.vue
Normal file
@ -0,0 +1,100 @@
|
||||
<template>
|
||||
<q-form>
|
||||
<q-input
|
||||
outlined
|
||||
readonly
|
||||
v-model="carWashingModel.id"
|
||||
label="id"
|
||||
hint=""
|
||||
/>
|
||||
<q-input
|
||||
outlined
|
||||
class="q-mt-sm"
|
||||
v-model="carWashingModel.code"
|
||||
@blur="onUpdate"
|
||||
label="名称"
|
||||
/>
|
||||
<q-select
|
||||
outlined
|
||||
style="margin-top: 10px"
|
||||
v-model="carWashingModel.linkSection"
|
||||
:options="sectionList"
|
||||
:map-options="true"
|
||||
:emit-value="true"
|
||||
@update:model-value="onUpdate"
|
||||
label="关联区段"
|
||||
></q-select>
|
||||
<q-field class="q-mt-lg" outlined label="所属集中站" stack-label>
|
||||
<template #control>
|
||||
<q-chip
|
||||
color="primary"
|
||||
text-color="white"
|
||||
v-for="(id, index) in carWashingModel.centralizedStations"
|
||||
:key="index"
|
||||
removable
|
||||
@remove="removeStation(index)"
|
||||
square
|
||||
>{{ getName(id) }}</q-chip
|
||||
>
|
||||
<q-btn round color="primary" size="xs" icon="add" @click="addStation" />
|
||||
</template>
|
||||
</q-field>
|
||||
</q-form>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useFormData } from 'src/components/DrawAppFormUtils';
|
||||
import { useDrawStore } from 'src/stores/draw-store';
|
||||
import { onMounted, reactive } from 'vue';
|
||||
import { Section } from 'src/graphics/section/Section';
|
||||
import { CarWashingData } from 'src/drawApp/graphics/CarWashingInteraction';
|
||||
import { Station } from 'src/graphics/station/Station';
|
||||
import AddCentralizedStationDialog from '../dialogs/AddCentralizedStationDialog.vue';
|
||||
import { useQuasar } from 'quasar';
|
||||
|
||||
const drawStore = useDrawStore();
|
||||
const sectionList: { label: string; value: number }[] = reactive([]);
|
||||
|
||||
const { data: carWashingModel, onUpdate } = useFormData(
|
||||
new CarWashingData(),
|
||||
drawStore.getDrawApp()
|
||||
);
|
||||
|
||||
onMounted(() => {
|
||||
const sections = drawStore
|
||||
.getDrawApp()
|
||||
.queryStore.queryByType<Section>(Section.Type);
|
||||
sections.forEach((p) => {
|
||||
sectionList.push({
|
||||
value: p.id,
|
||||
label: `${p.datas.code}`,
|
||||
});
|
||||
});
|
||||
});
|
||||
function removeStation(index: number) {
|
||||
carWashingModel.centralizedStations.splice(index, 1);
|
||||
onUpdate();
|
||||
}
|
||||
const $q = useQuasar();
|
||||
function addStation() {
|
||||
$q.dialog({
|
||||
title: '',
|
||||
message: '',
|
||||
component: AddCentralizedStationDialog,
|
||||
cancel: true,
|
||||
persistent: true,
|
||||
}).onOk((data: number) => {
|
||||
carWashingModel.centralizedStations.push(data);
|
||||
onUpdate();
|
||||
});
|
||||
}
|
||||
|
||||
function getName(id: number) {
|
||||
try {
|
||||
const station = drawStore.getDrawApp().queryStore.queryById<Station>(id);
|
||||
return station.datas.code;
|
||||
} catch (error) {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
</script>
|
95
src/components/draw-app/properties/FloodGateProperty.vue
Normal file
95
src/components/draw-app/properties/FloodGateProperty.vue
Normal file
@ -0,0 +1,95 @@
|
||||
<template>
|
||||
<q-form>
|
||||
<q-input outlined readonly v-model="floodGateModel.id" label="id" hint="" />
|
||||
<q-input
|
||||
outlined
|
||||
class="q-mt-sm"
|
||||
v-model="floodGateModel.code"
|
||||
@blur="onUpdate"
|
||||
label="名称"
|
||||
/>
|
||||
<q-select
|
||||
outlined
|
||||
style="margin-top: 10px"
|
||||
v-model="floodGateModel.linkSection"
|
||||
:options="sectionList"
|
||||
:map-options="true"
|
||||
:emit-value="true"
|
||||
@update:model-value="onUpdate"
|
||||
label="关联区段"
|
||||
></q-select>
|
||||
<q-field class="q-mt-lg" outlined label="所属集中站" stack-label>
|
||||
<template #control>
|
||||
<q-chip
|
||||
color="primary"
|
||||
text-color="white"
|
||||
v-for="(id, index) in floodGateModel.centralizedStations"
|
||||
:key="index"
|
||||
removable
|
||||
@remove="removeStation(index)"
|
||||
square
|
||||
>{{ getName(id) }}</q-chip
|
||||
>
|
||||
<q-btn round color="primary" size="xs" icon="add" @click="addStation" />
|
||||
</template>
|
||||
</q-field>
|
||||
</q-form>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useFormData } from 'src/components/DrawAppFormUtils';
|
||||
import { useDrawStore } from 'src/stores/draw-store';
|
||||
import { onMounted, reactive } from 'vue';
|
||||
import { Section } from 'src/graphics/section/Section';
|
||||
import { FloodGateData } from 'src/drawApp/graphics/FloodGateInteraction';
|
||||
import AddCentralizedStationDialog from '../dialogs/AddCentralizedStationDialog.vue';
|
||||
import { useQuasar } from 'quasar';
|
||||
import { Station } from 'src/graphics/station/Station';
|
||||
|
||||
const drawStore = useDrawStore();
|
||||
const sectionList: { label: string; value: number }[] = reactive([]);
|
||||
|
||||
const { data: floodGateModel, onUpdate } = useFormData(
|
||||
new FloodGateData(),
|
||||
drawStore.getDrawApp()
|
||||
);
|
||||
|
||||
onMounted(() => {
|
||||
const sections = drawStore
|
||||
.getDrawApp()
|
||||
.queryStore.queryByType<Section>(Section.Type);
|
||||
sections.forEach((p) => {
|
||||
sectionList.push({
|
||||
value: p.id,
|
||||
label: `${p.datas.code}`,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function removeStation(index: number) {
|
||||
floodGateModel.centralizedStations.splice(index, 1);
|
||||
onUpdate();
|
||||
}
|
||||
const $q = useQuasar();
|
||||
function addStation() {
|
||||
$q.dialog({
|
||||
title: '',
|
||||
message: '',
|
||||
component: AddCentralizedStationDialog,
|
||||
cancel: true,
|
||||
persistent: true,
|
||||
}).onOk((data: number) => {
|
||||
floodGateModel.centralizedStations.push(data);
|
||||
onUpdate();
|
||||
});
|
||||
}
|
||||
|
||||
function getName(id: number) {
|
||||
try {
|
||||
const station = drawStore.getDrawApp().queryStore.queryById<Station>(id);
|
||||
return station.datas.code;
|
||||
} catch (error) {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
</script>
|
101
src/components/draw-app/properties/GarageDoorProperty.vue
Normal file
101
src/components/draw-app/properties/GarageDoorProperty.vue
Normal file
@ -0,0 +1,101 @@
|
||||
<template>
|
||||
<q-form>
|
||||
<q-input
|
||||
outlined
|
||||
readonly
|
||||
v-model="garageDoorModel.id"
|
||||
label="id"
|
||||
hint=""
|
||||
/>
|
||||
<q-input
|
||||
outlined
|
||||
class="q-mt-sm"
|
||||
v-model="garageDoorModel.code"
|
||||
@blur="onUpdate"
|
||||
label="名称"
|
||||
/>
|
||||
<q-select
|
||||
outlined
|
||||
style="margin-top: 10px"
|
||||
v-model="garageDoorModel.linkSection"
|
||||
:options="sectionList"
|
||||
:map-options="true"
|
||||
:emit-value="true"
|
||||
@update:model-value="onUpdate"
|
||||
label="关联区段"
|
||||
></q-select>
|
||||
<q-field class="q-mt-lg" outlined label="所属集中站" stack-label>
|
||||
<template #control>
|
||||
<q-chip
|
||||
color="primary"
|
||||
text-color="white"
|
||||
v-for="(id, index) in garageDoorModel.centralizedStations"
|
||||
:key="index"
|
||||
removable
|
||||
@remove="removeStation(index)"
|
||||
square
|
||||
>{{ getName(id) }}</q-chip
|
||||
>
|
||||
<q-btn round color="primary" size="xs" icon="add" @click="addStation" />
|
||||
</template>
|
||||
</q-field>
|
||||
</q-form>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useFormData } from 'src/components/DrawAppFormUtils';
|
||||
import { useDrawStore } from 'src/stores/draw-store';
|
||||
import { onMounted, reactive } from 'vue';
|
||||
import { GarageDoorData } from 'src/drawApp/graphics/GarageDoorInteraction';
|
||||
import { Section } from 'src/graphics/section/Section';
|
||||
import AddCentralizedStationDialog from '../dialogs/AddCentralizedStationDialog.vue';
|
||||
import { useQuasar } from 'quasar';
|
||||
import { Station } from 'src/graphics/station/Station';
|
||||
|
||||
const drawStore = useDrawStore();
|
||||
const sectionList: { label: string; value: number }[] = reactive([]);
|
||||
|
||||
const { data: garageDoorModel, onUpdate } = useFormData(
|
||||
new GarageDoorData(),
|
||||
drawStore.getDrawApp()
|
||||
);
|
||||
|
||||
onMounted(() => {
|
||||
const sections = drawStore
|
||||
.getDrawApp()
|
||||
.queryStore.queryByType<Section>(Section.Type);
|
||||
sections.forEach((p) => {
|
||||
sectionList.push({
|
||||
value: p.id,
|
||||
label: `${p.datas.code}`,
|
||||
});
|
||||
});
|
||||
});
|
||||
const $q = useQuasar();
|
||||
function removeStation(index: number) {
|
||||
garageDoorModel.centralizedStations.splice(index, 1);
|
||||
onUpdate();
|
||||
}
|
||||
|
||||
function addStation() {
|
||||
$q.dialog({
|
||||
title: '',
|
||||
message: '',
|
||||
component: AddCentralizedStationDialog,
|
||||
cancel: true,
|
||||
persistent: true,
|
||||
}).onOk((data: number) => {
|
||||
garageDoorModel.centralizedStations.push(data);
|
||||
onUpdate();
|
||||
});
|
||||
}
|
||||
|
||||
function getName(id: number) {
|
||||
try {
|
||||
const station = drawStore.getDrawApp().queryStore.queryById<Station>(id);
|
||||
return station.datas.code;
|
||||
} catch (error) {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
</script>
|
@ -21,6 +21,9 @@ import { Turnout } from 'src/graphics/turnout/Turnout';
|
||||
import { ConcentrationDividingLine } from 'src/graphics/concentrationDividingLine/ConcentrationDividingLine';
|
||||
import { IbpBox } from 'src/graphics/ibpBox/IbpBox';
|
||||
import { PslBox } from 'src/graphics/pslBox/PslBox';
|
||||
import { GarageDoor } from 'src/graphics/garageDoor/GarageDoor';
|
||||
import { CarWashing } from 'src/graphics/carWashing/CarWashing';
|
||||
import { FloodGate } from 'src/graphics/floodGate/FloodGate';
|
||||
|
||||
export const drawCommonLayerList = [
|
||||
// 图层列表 默认显示的图层defaultShow: true
|
||||
@ -55,4 +58,7 @@ export const drawCommonLayerList = [
|
||||
value: ConcentrationDividingLine.Type,
|
||||
defaultShow: true,
|
||||
},
|
||||
{ label: '防淹门', value: GarageDoor.Type, defaultShow: true },
|
||||
{ label: '车库门', value: FloodGate.Type, defaultShow: true },
|
||||
{ label: '洗车机', value: CarWashing.Type, defaultShow: true },
|
||||
];
|
||||
|
@ -142,6 +142,21 @@ import { Dialog } from 'quasar';
|
||||
import { useDrawStore } from 'src/stores/draw-store';
|
||||
import { saveDraft } from 'src/api/DraftApi';
|
||||
import { SignalDraw } from 'src/graphics/signal/SignalDrawAssistant';
|
||||
import { CarWashingData } from './graphics/CarWashingInteraction';
|
||||
import {
|
||||
CarWashing,
|
||||
CarWashingTemplate,
|
||||
} from 'src/graphics/carWashing/CarWashing';
|
||||
import { CarWashingDraw } from 'src/graphics/carWashing/CarWashingDrawAssistant';
|
||||
import { FloodGateData } from './graphics/FloodGateInteraction';
|
||||
import { FloodGate, FloodGateTemplate } from 'src/graphics/floodGate/FloodGate';
|
||||
import { FloodGateDraw } from 'src/graphics/floodGate/FloodGateDrawAssistant';
|
||||
import { GarageDoorData } from './graphics/GarageDoorInteraction';
|
||||
import {
|
||||
GarageDoor,
|
||||
GarageDoorTemplate,
|
||||
} from 'src/graphics/garageDoor/GarageDoor';
|
||||
import { GarageDoorDraw } from 'src/graphics/garageDoor/GarageDoorDrawAssistant';
|
||||
|
||||
const UndoOptions: MenuItemOptions = {
|
||||
name: '撤销',
|
||||
@ -228,6 +243,9 @@ export function initCommonDrawApp(app: IDrawApp) {
|
||||
app,
|
||||
new ConcentrationDividingLineTemplate(new ConcentrationDividingLineData())
|
||||
);
|
||||
new CarWashingDraw(app, new CarWashingTemplate(new CarWashingData()));
|
||||
new FloodGateDraw(app, new FloodGateTemplate(new FloodGateData()));
|
||||
new GarageDoorDraw(app, new GarageDoorTemplate(new GarageDoorData()));
|
||||
DrawSignalInteraction.init(app);
|
||||
DrawStopPositionInteraction.init(app);
|
||||
DrawSpksSwitchInteraction.init(app);
|
||||
@ -437,6 +455,15 @@ export function loadCommonDrawDatas(
|
||||
storage.concentrationDividingLines.forEach((concentrationDividingLine) => {
|
||||
datas.push(new ConcentrationDividingLineData(concentrationDividingLine));
|
||||
});
|
||||
storage.floodGates.forEach((flood) => {
|
||||
datas.push(new FloodGateData(flood));
|
||||
});
|
||||
storage.carWashings.forEach((carWashing) => {
|
||||
datas.push(new CarWashingData(carWashing));
|
||||
});
|
||||
storage.garageDoors.forEach((garageDoor) => {
|
||||
datas.push(new GarageDoorData(garageDoor));
|
||||
});
|
||||
return datas;
|
||||
}
|
||||
|
||||
@ -523,6 +550,15 @@ export function saveCommonDrawDatas(app: IDrawApp) {
|
||||
storage.concentrationDividingLines.push(
|
||||
(concentrationDividingLineData as ConcentrationDividingLineData).data
|
||||
);
|
||||
} else if (g instanceof CarWashing) {
|
||||
const carWashingData = g.saveData();
|
||||
storage.carWashings.push((carWashingData as CarWashingData).data);
|
||||
} else if (g instanceof FloodGate) {
|
||||
const floodGateData = g.saveData();
|
||||
storage.floodGates.push((floodGateData as FloodGateData).data);
|
||||
} else if (g instanceof GarageDoor) {
|
||||
const garageDoorData = g.saveData();
|
||||
storage.garageDoors.push((garageDoorData as GarageDoorData).data);
|
||||
}
|
||||
});
|
||||
// storage.Platforms.forEach((item) => {
|
||||
|
88
src/drawApp/graphics/CarWashingInteraction.ts
Normal file
88
src/drawApp/graphics/CarWashingInteraction.ts
Normal file
@ -0,0 +1,88 @@
|
||||
import * as pb_1 from 'google-protobuf';
|
||||
import { FederatedMouseEvent } from 'pixi.js';
|
||||
import {
|
||||
CarWashing,
|
||||
ICarWashingData,
|
||||
} from 'src/graphics/carWashing/CarWashing';
|
||||
import { GraphicInteractionPlugin, JlGraphic, IGraphicScene } from 'jl-graphic';
|
||||
|
||||
import { graphicData } from 'src/protos/stationLayoutGraphics';
|
||||
import { GraphicDataBase } from './GraphicDataBase';
|
||||
|
||||
export class CarWashingData extends GraphicDataBase implements ICarWashingData {
|
||||
constructor(data?: graphicData.CarWashing) {
|
||||
let carWashing;
|
||||
if (!data) {
|
||||
carWashing = new graphicData.CarWashing({
|
||||
common: GraphicDataBase.defaultCommonInfo(CarWashing.Type),
|
||||
});
|
||||
} else {
|
||||
carWashing = data;
|
||||
}
|
||||
super(carWashing);
|
||||
}
|
||||
|
||||
public get data(): graphicData.CarWashing {
|
||||
return this.getData<graphicData.CarWashing>();
|
||||
}
|
||||
get code(): string {
|
||||
return this.data.code;
|
||||
}
|
||||
set code(v: string) {
|
||||
this.data.code = v;
|
||||
}
|
||||
get linkSection(): number {
|
||||
return this.data.linkSection;
|
||||
}
|
||||
set linkSection(v: number) {
|
||||
this.data.linkSection = v;
|
||||
}
|
||||
get centralizedStations(): number[] {
|
||||
return this.data.centralizedStations;
|
||||
}
|
||||
set centralizedStations(v: number[]) {
|
||||
this.data.centralizedStations = v;
|
||||
}
|
||||
clone(): CarWashingData {
|
||||
return new CarWashingData(this.data.cloneMessage());
|
||||
}
|
||||
copyFrom(data: CarWashingData): void {
|
||||
pb_1.Message.copyInto(data.data, this.data);
|
||||
}
|
||||
eq(other: CarWashingData): boolean {
|
||||
return pb_1.Message.equals(this.data, other.data);
|
||||
}
|
||||
}
|
||||
|
||||
export class CarWashingOperationInteraction extends GraphicInteractionPlugin<CarWashing> {
|
||||
static Name = 'car_washing_operation';
|
||||
constructor(scene: IGraphicScene) {
|
||||
super(CarWashingOperationInteraction.Name, scene);
|
||||
}
|
||||
static init(scene: IGraphicScene) {
|
||||
return new CarWashingOperationInteraction(scene);
|
||||
}
|
||||
filter(...grahpics: JlGraphic[]): CarWashing[] | undefined {
|
||||
return grahpics.filter((g): g is CarWashing => g.type === CarWashing.Type);
|
||||
}
|
||||
bind(g: CarWashing): void {
|
||||
g.eventMode = 'static';
|
||||
g.cursor = 'pointer';
|
||||
g.on('mousedown', this.onPress, this);
|
||||
}
|
||||
unbind(g: CarWashing): void {
|
||||
g.eventMode = 'none';
|
||||
g.cursor = 'default';
|
||||
g.off('mousedown', this.onPress, this);
|
||||
}
|
||||
onPress(e: FederatedMouseEvent) {
|
||||
const g = e.target as CarWashing;
|
||||
g.on('mouseleave', this.onRelease, this);
|
||||
g.on('mouseup', this.onRelease, this);
|
||||
}
|
||||
onRelease(e: FederatedMouseEvent) {
|
||||
const g = e.target as CarWashing;
|
||||
g.off('mouseleave', this.onRelease, this);
|
||||
g.off('mouseup', this.onRelease, this);
|
||||
}
|
||||
}
|
85
src/drawApp/graphics/FloodGateInteraction.ts
Normal file
85
src/drawApp/graphics/FloodGateInteraction.ts
Normal file
@ -0,0 +1,85 @@
|
||||
import * as pb_1 from 'google-protobuf';
|
||||
import { FederatedMouseEvent } from 'pixi.js';
|
||||
import { FloodGate, IFloodGateData } from 'src/graphics/floodGate/FloodGate';
|
||||
import { GraphicInteractionPlugin, JlGraphic, IGraphicScene } from 'jl-graphic';
|
||||
|
||||
import { graphicData } from 'src/protos/stationLayoutGraphics';
|
||||
import { GraphicDataBase } from './GraphicDataBase';
|
||||
|
||||
export class FloodGateData extends GraphicDataBase implements IFloodGateData {
|
||||
constructor(data?: graphicData.FloodGate) {
|
||||
let floodGate;
|
||||
if (!data) {
|
||||
floodGate = new graphicData.FloodGate({
|
||||
common: GraphicDataBase.defaultCommonInfo(FloodGate.Type),
|
||||
});
|
||||
} else {
|
||||
floodGate = data;
|
||||
}
|
||||
super(floodGate);
|
||||
}
|
||||
|
||||
public get data(): graphicData.FloodGate {
|
||||
return this.getData<graphicData.FloodGate>();
|
||||
}
|
||||
get code(): string {
|
||||
return this.data.code;
|
||||
}
|
||||
set code(v: string) {
|
||||
this.data.code = v;
|
||||
}
|
||||
get linkSection(): number {
|
||||
return this.data.linkSection;
|
||||
}
|
||||
set linkSection(v: number) {
|
||||
this.data.linkSection = v;
|
||||
}
|
||||
get centralizedStations(): number[] {
|
||||
return this.data.centralizedStations;
|
||||
}
|
||||
set centralizedStations(v: number[]) {
|
||||
this.data.centralizedStations = v;
|
||||
}
|
||||
clone(): FloodGateData {
|
||||
return new FloodGateData(this.data.cloneMessage());
|
||||
}
|
||||
copyFrom(data: FloodGateData): void {
|
||||
pb_1.Message.copyInto(data.data, this.data);
|
||||
}
|
||||
eq(other: FloodGateData): boolean {
|
||||
return pb_1.Message.equals(this.data, other.data);
|
||||
}
|
||||
}
|
||||
|
||||
export class FloodGateOperationInteraction extends GraphicInteractionPlugin<FloodGate> {
|
||||
static Name = 'flood_gate_operation';
|
||||
constructor(scene: IGraphicScene) {
|
||||
super(FloodGateOperationInteraction.Name, scene);
|
||||
}
|
||||
static init(scene: IGraphicScene) {
|
||||
return new FloodGateOperationInteraction(scene);
|
||||
}
|
||||
filter(...grahpics: JlGraphic[]): FloodGate[] | undefined {
|
||||
return grahpics.filter((g): g is FloodGate => g.type === FloodGate.Type);
|
||||
}
|
||||
bind(g: FloodGate): void {
|
||||
g.eventMode = 'static';
|
||||
g.cursor = 'pointer';
|
||||
g.on('mousedown', this.onPress, this);
|
||||
}
|
||||
unbind(g: FloodGate): void {
|
||||
g.eventMode = 'none';
|
||||
g.cursor = 'default';
|
||||
g.off('mousedown', this.onPress, this);
|
||||
}
|
||||
onPress(e: FederatedMouseEvent) {
|
||||
const g = e.target as FloodGate;
|
||||
g.on('mouseleave', this.onRelease, this);
|
||||
g.on('mouseup', this.onRelease, this);
|
||||
}
|
||||
onRelease(e: FederatedMouseEvent) {
|
||||
const g = e.target as FloodGate;
|
||||
g.off('mouseleave', this.onRelease, this);
|
||||
g.off('mouseup', this.onRelease, this);
|
||||
}
|
||||
}
|
88
src/drawApp/graphics/GarageDoorInteraction.ts
Normal file
88
src/drawApp/graphics/GarageDoorInteraction.ts
Normal file
@ -0,0 +1,88 @@
|
||||
import * as pb_1 from 'google-protobuf';
|
||||
import { FederatedMouseEvent } from 'pixi.js';
|
||||
import {
|
||||
GarageDoor,
|
||||
IGarageDoorData,
|
||||
} from 'src/graphics/garageDoor/GarageDoor';
|
||||
import { GraphicInteractionPlugin, JlGraphic, IGraphicScene } from 'jl-graphic';
|
||||
|
||||
import { graphicData } from 'src/protos/stationLayoutGraphics';
|
||||
import { GraphicDataBase } from './GraphicDataBase';
|
||||
|
||||
export class GarageDoorData extends GraphicDataBase implements IGarageDoorData {
|
||||
constructor(data?: graphicData.GarageDoor) {
|
||||
let garageDoor;
|
||||
if (!data) {
|
||||
garageDoor = new graphicData.GarageDoor({
|
||||
common: GraphicDataBase.defaultCommonInfo(GarageDoor.Type),
|
||||
});
|
||||
} else {
|
||||
garageDoor = data;
|
||||
}
|
||||
super(garageDoor);
|
||||
}
|
||||
|
||||
public get data(): graphicData.GarageDoor {
|
||||
return this.getData<graphicData.GarageDoor>();
|
||||
}
|
||||
get code(): string {
|
||||
return this.data.code;
|
||||
}
|
||||
set code(v: string) {
|
||||
this.data.code = v;
|
||||
}
|
||||
get linkSection(): number {
|
||||
return this.data.linkSection;
|
||||
}
|
||||
set linkSection(v: number) {
|
||||
this.data.linkSection = v;
|
||||
}
|
||||
get centralizedStations(): number[] {
|
||||
return this.data.centralizedStations;
|
||||
}
|
||||
set centralizedStations(v: number[]) {
|
||||
this.data.centralizedStations = v;
|
||||
}
|
||||
clone(): GarageDoorData {
|
||||
return new GarageDoorData(this.data.cloneMessage());
|
||||
}
|
||||
copyFrom(data: GarageDoorData): void {
|
||||
pb_1.Message.copyInto(data.data, this.data);
|
||||
}
|
||||
eq(other: GarageDoorData): boolean {
|
||||
return pb_1.Message.equals(this.data, other.data);
|
||||
}
|
||||
}
|
||||
|
||||
export class GarageDoorOperationInteraction extends GraphicInteractionPlugin<GarageDoor> {
|
||||
static Name = 'garage_door_operation';
|
||||
constructor(scene: IGraphicScene) {
|
||||
super(GarageDoorOperationInteraction.Name, scene);
|
||||
}
|
||||
static init(scene: IGraphicScene) {
|
||||
return new GarageDoorOperationInteraction(scene);
|
||||
}
|
||||
filter(...grahpics: JlGraphic[]): GarageDoor[] | undefined {
|
||||
return grahpics.filter((g): g is GarageDoor => g.type === GarageDoor.Type);
|
||||
}
|
||||
bind(g: GarageDoor): void {
|
||||
g.eventMode = 'static';
|
||||
g.cursor = 'pointer';
|
||||
g.on('mousedown', this.onPress, this);
|
||||
}
|
||||
unbind(g: GarageDoor): void {
|
||||
g.eventMode = 'none';
|
||||
g.cursor = 'default';
|
||||
g.off('mousedown', this.onPress, this);
|
||||
}
|
||||
onPress(e: FederatedMouseEvent) {
|
||||
const g = e.target as GarageDoor;
|
||||
g.on('mouseleave', this.onRelease, this);
|
||||
g.on('mouseup', this.onRelease, this);
|
||||
}
|
||||
onRelease(e: FederatedMouseEvent) {
|
||||
const g = e.target as GarageDoor;
|
||||
g.off('mouseleave', this.onRelease, this);
|
||||
g.off('mouseup', this.onRelease, this);
|
||||
}
|
||||
}
|
@ -21,6 +21,27 @@ import {
|
||||
Signal,
|
||||
KilometerSystem,
|
||||
} from 'src/graphics/signal/Signal';
|
||||
import {
|
||||
FloodGateData,
|
||||
FloodGateOperationInteraction,
|
||||
} from './graphics/FloodGateInteraction';
|
||||
import { FloodGate, FloodGateTemplate } from 'src/graphics/floodGate/FloodGate';
|
||||
import {
|
||||
CarWashingData,
|
||||
CarWashingOperationInteraction,
|
||||
} from './graphics/CarWashingInteraction';
|
||||
import {
|
||||
CarWashing,
|
||||
CarWashingTemplate,
|
||||
} from 'src/graphics/carWashing/CarWashing';
|
||||
import {
|
||||
GarageDoorData,
|
||||
GarageDoorOperationInteraction,
|
||||
} from './graphics/GarageDoorInteraction';
|
||||
import {
|
||||
GarageDoor,
|
||||
GarageDoorTemplate,
|
||||
} from 'src/graphics/garageDoor/GarageDoor';
|
||||
import {
|
||||
PlatformData,
|
||||
PlatformOperateInteraction,
|
||||
@ -161,10 +182,16 @@ import {
|
||||
import { errorNotify, successNotify } from 'src/utils/CommonNotify';
|
||||
import { removeAllTrain } from 'src/api/Simulation';
|
||||
import { ApiError } from 'src/boot/axios';
|
||||
import { IbpBox,IbpBoxTemplate } from 'src/graphics/ibpBox/IbpBox';
|
||||
import { PslBox,PslBoxTemplate } from 'src/graphics/pslBox/PslBox';
|
||||
import { PslBoxData, PslBoxOperateInteraction } from './graphics/PslBoxInteraction';
|
||||
import { IbpBoxData, IbpBoxOperateInteraction } from './graphics/IbpBoxInteraction';
|
||||
import { IbpBox, IbpBoxTemplate } from 'src/graphics/ibpBox/IbpBox';
|
||||
import { PslBox, PslBoxTemplate } from 'src/graphics/pslBox/PslBox';
|
||||
import {
|
||||
PslBoxData,
|
||||
PslBoxOperateInteraction,
|
||||
} from './graphics/PslBoxInteraction';
|
||||
import {
|
||||
IbpBoxData,
|
||||
IbpBoxOperateInteraction,
|
||||
} from './graphics/IbpBoxInteraction';
|
||||
|
||||
const showOptions: MenuItemOptions = {
|
||||
name: '显示控制',
|
||||
@ -227,6 +254,9 @@ export const layerList = [
|
||||
{ label: '轨道区段', value: TrackSection.Type, defaultShow: false },
|
||||
{ label: '轨道逻辑区段', value: TrackLogicSection.Type, defaultShow: false },
|
||||
{ label: '自动折返按钮箱', value: AutoReturnBox.Type, defaultShow: true },
|
||||
{ label: '防淹门', value: GarageDoor.Type, defaultShow: true },
|
||||
{ label: '车库门', value: FloodGate.Type, defaultShow: true },
|
||||
{ label: '洗车机', value: CarWashing.Type, defaultShow: true },
|
||||
];
|
||||
|
||||
let lineScene: IGraphicScene;
|
||||
@ -295,6 +325,9 @@ export function initLineScene(lineApp: IGraphicApp, sceneName: string) {
|
||||
new AutoReturnBoxData(),
|
||||
new AutoReturnBoxState()
|
||||
),
|
||||
new CarWashingTemplate(new CarWashingData()),
|
||||
new GarageDoorTemplate(new GarageDoorData()),
|
||||
new FloodGateTemplate(new FloodGateData()),
|
||||
];
|
||||
lineScene.registerGraphicTemplates(...graphicTemplate);
|
||||
SignalOperateInteraction.init(lineScene);
|
||||
@ -311,6 +344,9 @@ export function initLineScene(lineApp: IGraphicApp, sceneName: string) {
|
||||
AutoReturnBoxOperationInteraction.init(lineScene);
|
||||
PslBoxOperateInteraction.init(lineScene);
|
||||
IbpBoxOperateInteraction.init(lineScene);
|
||||
CarWashingOperationInteraction.init(lineScene);
|
||||
GarageDoorOperationInteraction.init(lineScene);
|
||||
FloodGateOperationInteraction.init(lineScene);
|
||||
if (categoryType === CategoryType.TH) {
|
||||
GatedBoxOperateInteraction.init(lineScene);
|
||||
}
|
||||
@ -606,6 +642,15 @@ export async function loadLineDatas(): Promise<IGraphicStorage> {
|
||||
storage.pslBoxs.forEach((pslBox) => {
|
||||
datas.push(new PslBoxData(pslBox));
|
||||
});
|
||||
storage.carWashings.forEach((carWashing) => {
|
||||
datas.push(new CarWashingData(carWashing));
|
||||
});
|
||||
storage.garageDoors.forEach((garageDoor) => {
|
||||
datas.push(new GarageDoorData(garageDoor));
|
||||
});
|
||||
storage.floodGates.forEach((floodGate) => {
|
||||
datas.push(new FloodGateData(floodGate));
|
||||
});
|
||||
// const linkIdGenerator = new IdGenerator(Link.Type);
|
||||
// storage.CalculateLink.forEach((link) => {
|
||||
// const g = new LinkData(link);
|
||||
|
89
src/graphics/carWashing/CarWashing.ts
Normal file
89
src/graphics/carWashing/CarWashing.ts
Normal file
@ -0,0 +1,89 @@
|
||||
import { Graphics } from 'pixi.js';
|
||||
import {
|
||||
GraphicData,
|
||||
JlGraphic,
|
||||
JlGraphicTemplate,
|
||||
VectorText,
|
||||
} from 'jl-graphic';
|
||||
|
||||
export interface ICarWashingData extends GraphicData {
|
||||
get code(): string;
|
||||
set code(v: string);
|
||||
get linkSection(): number;
|
||||
set linkSection(v: number);
|
||||
get centralizedStations(): number[];
|
||||
set centralizedStations(v: number[]);
|
||||
clone(): ICarWashingData;
|
||||
copyFrom(data: ICarWashingData): void;
|
||||
eq(other: ICarWashingData): boolean;
|
||||
}
|
||||
|
||||
const carWashingConsts = {
|
||||
codeFontSize: 12,
|
||||
codeColor: 0xffffff,
|
||||
bodyRectLineColor: 0xffffff,
|
||||
bodyRectLineWidth: 2,
|
||||
bodyRectWidth: 10,
|
||||
bodyRectHeight: 20,
|
||||
bodyColor: 0x000000,
|
||||
};
|
||||
export class CarWashing extends JlGraphic {
|
||||
static Type = 'carWashing';
|
||||
codeGraph: VectorText = new VectorText('');
|
||||
rectBody: Graphics = new Graphics();
|
||||
|
||||
constructor() {
|
||||
super(CarWashing.Type);
|
||||
this.addChild(this.codeGraph);
|
||||
this.addChild(this.rectBody);
|
||||
this.codeGraph.name = 'carw_code';
|
||||
}
|
||||
get code(): string {
|
||||
return this.datas.code;
|
||||
}
|
||||
get datas(): ICarWashingData {
|
||||
return this.getDatas<ICarWashingData>();
|
||||
}
|
||||
doRepaint(): void {
|
||||
const codeGraph = this.codeGraph;
|
||||
codeGraph.text = this.datas.code;
|
||||
codeGraph.style.fill = carWashingConsts.codeColor;
|
||||
codeGraph.setVectorFontSize(carWashingConsts.codeFontSize);
|
||||
codeGraph.anchor.set(0.5);
|
||||
const codeTransform = this.datas?.childTransforms?.find(
|
||||
(item) => item.name === 'carw_code'
|
||||
);
|
||||
if (codeTransform) {
|
||||
const position = codeTransform?.transform.position;
|
||||
const rotation = codeTransform?.transform?.rotation;
|
||||
codeGraph.position.set(position?.x, position?.y);
|
||||
codeGraph.rotation = rotation || 0;
|
||||
} else {
|
||||
codeGraph.position.set(0, -30);
|
||||
}
|
||||
this.rectBody.clear();
|
||||
this.rectBody.beginFill(carWashingConsts.bodyColor, 0);
|
||||
this.rectBody.lineStyle(
|
||||
carWashingConsts.bodyRectLineWidth,
|
||||
carWashingConsts.bodyRectLineColor
|
||||
);
|
||||
this.rectBody.drawRect(
|
||||
-carWashingConsts.bodyRectWidth / 2,
|
||||
-carWashingConsts.bodyRectHeight / 2,
|
||||
carWashingConsts.bodyRectWidth,
|
||||
carWashingConsts.bodyRectHeight
|
||||
);
|
||||
this.rectBody.endFill();
|
||||
}
|
||||
}
|
||||
|
||||
export class CarWashingTemplate extends JlGraphicTemplate<CarWashing> {
|
||||
constructor(dataTemplate: ICarWashingData) {
|
||||
super(CarWashing.Type, { dataTemplate });
|
||||
}
|
||||
new(): CarWashing {
|
||||
const carWashing = new CarWashing();
|
||||
carWashing.loadData(this.datas);
|
||||
return carWashing;
|
||||
}
|
||||
}
|
128
src/graphics/carWashing/CarWashingDrawAssistant.ts
Normal file
128
src/graphics/carWashing/CarWashingDrawAssistant.ts
Normal file
@ -0,0 +1,128 @@
|
||||
import { DisplayObject, FederatedMouseEvent, Point } from 'pixi.js';
|
||||
import {
|
||||
AbsorbableLine,
|
||||
AbsorbablePosition,
|
||||
GraphicDrawAssistant,
|
||||
GraphicInteractionPlugin,
|
||||
GraphicTransformEvent,
|
||||
IDrawApp,
|
||||
JlGraphic,
|
||||
} from 'jl-graphic';
|
||||
import { CarWashing, CarWashingTemplate, ICarWashingData } from './CarWashing';
|
||||
|
||||
export interface ICarWashingDataDrawOptions {
|
||||
newData: () => ICarWashingData;
|
||||
}
|
||||
export class CarWashingDraw extends GraphicDrawAssistant<
|
||||
CarWashingTemplate,
|
||||
ICarWashingData
|
||||
> {
|
||||
_carWashing: CarWashing | null = null;
|
||||
constructor(app: IDrawApp, template: CarWashingTemplate) {
|
||||
super(
|
||||
app,
|
||||
template,
|
||||
'svguse:../../drawIcon.svg#icon-car-washing',
|
||||
'洗车机CarWashing'
|
||||
);
|
||||
CarWashingInteraction.init(app);
|
||||
}
|
||||
public get carWashing(): CarWashing {
|
||||
if (!this._carWashing) {
|
||||
this._carWashing = this.graphicTemplate.new();
|
||||
this._carWashing.loadData(this.graphicTemplate.datas);
|
||||
this.container.addChild(this._carWashing);
|
||||
}
|
||||
return this._carWashing;
|
||||
}
|
||||
|
||||
onLeftUp(e: FederatedMouseEvent): void {
|
||||
this.container.position.copyFrom(this.toCanvasCoordinates(e.global));
|
||||
this.createAndStore(true);
|
||||
}
|
||||
|
||||
redraw(p: Point): void {
|
||||
this.carWashing.repaint();
|
||||
this.container.position.set(p.x, p.y);
|
||||
}
|
||||
|
||||
prepareData(data: ICarWashingData): boolean {
|
||||
data.transform = this.container.saveTransform();
|
||||
data.code = 'CarWash';
|
||||
return true;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 构建吸附线
|
||||
* @param carWashing
|
||||
*/
|
||||
function buildAbsorbablePositions(
|
||||
carWashing: CarWashing
|
||||
): AbsorbablePosition[] {
|
||||
const aps: AbsorbablePosition[] = [];
|
||||
const carWashings = carWashing.queryStore.queryByType<CarWashing>(
|
||||
CarWashing.Type
|
||||
);
|
||||
const canvas = carWashing.getCanvas();
|
||||
carWashings.forEach((item) => {
|
||||
if (item.id === carWashing.id) {
|
||||
return;
|
||||
}
|
||||
const ala = new AbsorbableLine(
|
||||
new Point(item.x, 0),
|
||||
new Point(item.x, canvas.height)
|
||||
);
|
||||
const alb = new AbsorbableLine(
|
||||
new Point(0, item.y),
|
||||
new Point(canvas.width, item.y)
|
||||
);
|
||||
aps.push(ala);
|
||||
aps.push(alb);
|
||||
});
|
||||
return aps;
|
||||
}
|
||||
|
||||
export class CarWashingInteraction extends GraphicInteractionPlugin<CarWashing> {
|
||||
static Name = 'car_washing_transform';
|
||||
constructor(app: IDrawApp) {
|
||||
super(CarWashingInteraction.Name, app);
|
||||
}
|
||||
static init(app: IDrawApp) {
|
||||
return new CarWashingInteraction(app);
|
||||
}
|
||||
filter(...grahpics: JlGraphic[]): CarWashing[] | undefined {
|
||||
return grahpics
|
||||
.filter((g) => g.type === CarWashing.Type)
|
||||
.map((g) => g as CarWashing);
|
||||
}
|
||||
bind(g: CarWashing): void {
|
||||
g.eventMode = 'static';
|
||||
g.cursor = 'pointer';
|
||||
g.scalable = true;
|
||||
g.rotatable = true;
|
||||
g.codeGraph.draggable = true;
|
||||
g.codeGraph.selectable = true;
|
||||
g.codeGraph.rotatable = true;
|
||||
g.codeGraph.transformSave = true;
|
||||
g.codeGraph.eventMode = 'static';
|
||||
g.on('transformstart', this.transformstart, this);
|
||||
}
|
||||
unbind(g: CarWashing): void {
|
||||
g.eventMode = 'none';
|
||||
g.scalable = false;
|
||||
g.rotatable = false;
|
||||
g.codeGraph.draggable = false;
|
||||
g.codeGraph.selectable = false;
|
||||
g.codeGraph.rotatable = false;
|
||||
g.codeGraph.transformSave = false;
|
||||
g.codeGraph.eventMode = 'none';
|
||||
g.off('transformstart', this.transformstart, this);
|
||||
}
|
||||
transformstart(e: GraphicTransformEvent) {
|
||||
const target = e.target as DisplayObject;
|
||||
const carWashing = target.getGraphic() as CarWashing;
|
||||
carWashing.getGraphicApp().setOptions({
|
||||
absorbablePositions: buildAbsorbablePositions(carWashing),
|
||||
});
|
||||
}
|
||||
}
|
99
src/graphics/floodGate/FloodGate.ts
Normal file
99
src/graphics/floodGate/FloodGate.ts
Normal file
@ -0,0 +1,99 @@
|
||||
import { Graphics } from 'pixi.js';
|
||||
import {
|
||||
GraphicData,
|
||||
JlGraphic,
|
||||
JlGraphicTemplate,
|
||||
VectorText,
|
||||
} from 'jl-graphic';
|
||||
|
||||
export interface IFloodGateData extends GraphicData {
|
||||
get code(): string;
|
||||
set code(v: string);
|
||||
get linkSection(): number;
|
||||
set linkSection(v: number);
|
||||
get centralizedStations(): number[];
|
||||
set centralizedStations(v: number[]);
|
||||
clone(): IFloodGateData;
|
||||
copyFrom(data: IFloodGateData): void;
|
||||
eq(other: IFloodGateData): boolean;
|
||||
}
|
||||
|
||||
const floodGateConsts = {
|
||||
codeFontSize: 12,
|
||||
codeColor: 0xffffff,
|
||||
bodyLineColor: 0xffffff,
|
||||
bodyLineWidth: 2,
|
||||
bodyColor: 0x000000,
|
||||
bodyRectWidth: 10,
|
||||
bodyRectHeight: 20,
|
||||
};
|
||||
export class FloodGate extends JlGraphic {
|
||||
static Type = 'floodGate';
|
||||
codeGraph: VectorText = new VectorText('');
|
||||
lineBody: Graphics = new Graphics();
|
||||
|
||||
constructor() {
|
||||
super(FloodGate.Type);
|
||||
this.addChild(this.codeGraph);
|
||||
this.addChild(this.lineBody);
|
||||
this.codeGraph.name = 'flood_code';
|
||||
}
|
||||
get code(): string {
|
||||
return this.datas.code;
|
||||
}
|
||||
get datas(): IFloodGateData {
|
||||
return this.getDatas<IFloodGateData>();
|
||||
}
|
||||
doRepaint(): void {
|
||||
const codeGraph = this.codeGraph;
|
||||
codeGraph.text = this.datas.code;
|
||||
codeGraph.style.fill = floodGateConsts.codeColor;
|
||||
codeGraph.setVectorFontSize(floodGateConsts.codeFontSize);
|
||||
codeGraph.anchor.set(0.5);
|
||||
const codeTransform = this.datas?.childTransforms?.find(
|
||||
(item) => item.name === 'flood_code'
|
||||
);
|
||||
if (codeTransform) {
|
||||
const position = codeTransform?.transform.position;
|
||||
const rotation = codeTransform?.transform?.rotation;
|
||||
codeGraph.position.set(position?.x, position?.y);
|
||||
codeGraph.rotation = rotation || 0;
|
||||
} else {
|
||||
codeGraph.position.set(0, -30);
|
||||
}
|
||||
this.lineBody.clear();
|
||||
this.lineBody.lineStyle(
|
||||
floodGateConsts.bodyLineWidth,
|
||||
floodGateConsts.bodyLineColor
|
||||
);
|
||||
this.lineBody.moveTo(
|
||||
-floodGateConsts.bodyRectWidth / 2,
|
||||
-floodGateConsts.bodyRectHeight / 2
|
||||
);
|
||||
this.lineBody.lineTo(
|
||||
floodGateConsts.bodyRectWidth / 2,
|
||||
-floodGateConsts.bodyRectHeight / 2
|
||||
);
|
||||
this.lineBody.moveTo(
|
||||
-floodGateConsts.bodyRectWidth / 2,
|
||||
floodGateConsts.bodyRectHeight / 2
|
||||
);
|
||||
this.lineBody.lineTo(
|
||||
floodGateConsts.bodyRectWidth / 2,
|
||||
floodGateConsts.bodyRectHeight / 2
|
||||
);
|
||||
this.lineBody.moveTo(0, -floodGateConsts.bodyRectHeight / 2);
|
||||
this.lineBody.lineTo(0, floodGateConsts.bodyRectHeight / 2);
|
||||
}
|
||||
}
|
||||
|
||||
export class FloodGateTemplate extends JlGraphicTemplate<FloodGate> {
|
||||
constructor(dataTemplate: IFloodGateData) {
|
||||
super(FloodGate.Type, { dataTemplate });
|
||||
}
|
||||
new(): FloodGate {
|
||||
const floodGate = new FloodGate();
|
||||
floodGate.loadData(this.datas);
|
||||
return floodGate;
|
||||
}
|
||||
}
|
126
src/graphics/floodGate/FloodGateDrawAssistant.ts
Normal file
126
src/graphics/floodGate/FloodGateDrawAssistant.ts
Normal file
@ -0,0 +1,126 @@
|
||||
import { DisplayObject, FederatedMouseEvent, Point } from 'pixi.js';
|
||||
import {
|
||||
AbsorbableLine,
|
||||
AbsorbablePosition,
|
||||
GraphicDrawAssistant,
|
||||
GraphicInteractionPlugin,
|
||||
GraphicTransformEvent,
|
||||
IDrawApp,
|
||||
JlGraphic,
|
||||
} from 'jl-graphic';
|
||||
import { FloodGate, FloodGateTemplate, IFloodGateData } from './FloodGate';
|
||||
|
||||
export interface IFloodGateDataDrawOptions {
|
||||
newData: () => IFloodGateData;
|
||||
}
|
||||
export class FloodGateDraw extends GraphicDrawAssistant<
|
||||
FloodGateTemplate,
|
||||
IFloodGateData
|
||||
> {
|
||||
_floodGate: FloodGate | null = null;
|
||||
constructor(app: IDrawApp, template: FloodGateTemplate) {
|
||||
super(
|
||||
app,
|
||||
template,
|
||||
'svguse:../../drawIcon.svg#icon-flood-gate',
|
||||
'车库门FloodGate'
|
||||
);
|
||||
FloodGateInteraction.init(app);
|
||||
}
|
||||
public get floodGate(): FloodGate {
|
||||
if (!this._floodGate) {
|
||||
this._floodGate = this.graphicTemplate.new();
|
||||
this._floodGate.loadData(this.graphicTemplate.datas);
|
||||
this.container.addChild(this._floodGate);
|
||||
}
|
||||
return this._floodGate;
|
||||
}
|
||||
|
||||
onLeftUp(e: FederatedMouseEvent): void {
|
||||
this.container.position.copyFrom(this.toCanvasCoordinates(e.global));
|
||||
this.createAndStore(true);
|
||||
}
|
||||
|
||||
redraw(p: Point): void {
|
||||
this.floodGate.repaint();
|
||||
this.container.position.set(p.x, p.y);
|
||||
}
|
||||
|
||||
prepareData(data: IFloodGateData): boolean {
|
||||
data.transform = this.container.saveTransform();
|
||||
data.code = 'FloodGate';
|
||||
return true;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 构建吸附线
|
||||
* @param floodGate
|
||||
*/
|
||||
function buildAbsorbablePositions(floodGate: FloodGate): AbsorbablePosition[] {
|
||||
const aps: AbsorbablePosition[] = [];
|
||||
const floodGates = floodGate.queryStore.queryByType<FloodGate>(
|
||||
FloodGate.Type
|
||||
);
|
||||
const canvas = floodGate.getCanvas();
|
||||
floodGates.forEach((item) => {
|
||||
if (item.id === floodGate.id) {
|
||||
return;
|
||||
}
|
||||
const ala = new AbsorbableLine(
|
||||
new Point(item.x, 0),
|
||||
new Point(item.x, canvas.height)
|
||||
);
|
||||
const alb = new AbsorbableLine(
|
||||
new Point(0, item.y),
|
||||
new Point(canvas.width, item.y)
|
||||
);
|
||||
aps.push(ala);
|
||||
aps.push(alb);
|
||||
});
|
||||
return aps;
|
||||
}
|
||||
|
||||
export class FloodGateInteraction extends GraphicInteractionPlugin<FloodGate> {
|
||||
static Name = 'flood_gate_transform';
|
||||
constructor(app: IDrawApp) {
|
||||
super(FloodGateInteraction.Name, app);
|
||||
}
|
||||
static init(app: IDrawApp) {
|
||||
return new FloodGateInteraction(app);
|
||||
}
|
||||
filter(...grahpics: JlGraphic[]): FloodGate[] | undefined {
|
||||
return grahpics
|
||||
.filter((g) => g.type === FloodGate.Type)
|
||||
.map((g) => g as FloodGate);
|
||||
}
|
||||
bind(g: FloodGate): void {
|
||||
g.eventMode = 'static';
|
||||
g.cursor = 'pointer';
|
||||
g.scalable = true;
|
||||
g.rotatable = true;
|
||||
g.codeGraph.draggable = true;
|
||||
g.codeGraph.selectable = true;
|
||||
g.codeGraph.rotatable = true;
|
||||
g.codeGraph.transformSave = true;
|
||||
g.codeGraph.eventMode = 'static';
|
||||
g.on('transformstart', this.transformstart, this);
|
||||
}
|
||||
unbind(g: FloodGate): void {
|
||||
g.eventMode = 'none';
|
||||
g.scalable = false;
|
||||
g.rotatable = false;
|
||||
g.codeGraph.draggable = false;
|
||||
g.codeGraph.selectable = false;
|
||||
g.codeGraph.rotatable = false;
|
||||
g.codeGraph.transformSave = false;
|
||||
g.codeGraph.eventMode = 'none';
|
||||
g.off('transformstart', this.transformstart, this);
|
||||
}
|
||||
transformstart(e: GraphicTransformEvent) {
|
||||
const target = e.target as DisplayObject;
|
||||
const floodGate = target.getGraphic() as FloodGate;
|
||||
floodGate.getGraphicApp().setOptions({
|
||||
absorbablePositions: buildAbsorbablePositions(floodGate),
|
||||
});
|
||||
}
|
||||
}
|
99
src/graphics/garageDoor/GarageDoor.ts
Normal file
99
src/graphics/garageDoor/GarageDoor.ts
Normal file
@ -0,0 +1,99 @@
|
||||
import { Graphics } from 'pixi.js';
|
||||
import {
|
||||
GraphicData,
|
||||
JlGraphic,
|
||||
JlGraphicTemplate,
|
||||
VectorText,
|
||||
} from 'jl-graphic';
|
||||
|
||||
export interface IGarageDoorData extends GraphicData {
|
||||
get code(): string;
|
||||
set code(v: string);
|
||||
get linkSection(): number;
|
||||
set linkSection(v: number);
|
||||
get centralizedStations(): number[];
|
||||
set centralizedStations(v: number[]);
|
||||
clone(): IGarageDoorData;
|
||||
copyFrom(data: IGarageDoorData): void;
|
||||
eq(other: IGarageDoorData): boolean;
|
||||
}
|
||||
|
||||
const garageConsts = {
|
||||
codeFontSize: 12,
|
||||
codeColor: 0xffffff,
|
||||
bodyLineColor: 0xffffff,
|
||||
bodyLineWidth: 2,
|
||||
bodyColor: 0x000000,
|
||||
bodyRectWidth: 10,
|
||||
bodyRectHeight: 20,
|
||||
};
|
||||
export class GarageDoor extends JlGraphic {
|
||||
static Type = 'garageDoor';
|
||||
codeGraph: VectorText = new VectorText('');
|
||||
lineBody: Graphics = new Graphics();
|
||||
|
||||
constructor() {
|
||||
super(GarageDoor.Type);
|
||||
this.addChild(this.codeGraph);
|
||||
this.addChild(this.lineBody);
|
||||
this.codeGraph.name = 'garage_code';
|
||||
}
|
||||
get code(): string {
|
||||
return this.datas.code;
|
||||
}
|
||||
get datas(): IGarageDoorData {
|
||||
return this.getDatas<IGarageDoorData>();
|
||||
}
|
||||
doRepaint(): void {
|
||||
const codeGraph = this.codeGraph;
|
||||
codeGraph.text = this.datas.code;
|
||||
codeGraph.style.fill = garageConsts.codeColor;
|
||||
codeGraph.setVectorFontSize(garageConsts.codeFontSize);
|
||||
codeGraph.anchor.set(0.5);
|
||||
const codeTransform = this.datas?.childTransforms?.find(
|
||||
(item) => item.name === 'garage_code'
|
||||
);
|
||||
if (codeTransform) {
|
||||
const position = codeTransform?.transform.position;
|
||||
const rotation = codeTransform?.transform?.rotation;
|
||||
codeGraph.position.set(position?.x, position?.y);
|
||||
codeGraph.rotation = rotation || 0;
|
||||
} else {
|
||||
codeGraph.position.set(0, -30);
|
||||
}
|
||||
this.lineBody.clear();
|
||||
this.lineBody.lineStyle(
|
||||
garageConsts.bodyLineWidth,
|
||||
garageConsts.bodyLineColor
|
||||
);
|
||||
this.lineBody.moveTo(
|
||||
-garageConsts.bodyRectWidth / 2,
|
||||
-garageConsts.bodyRectHeight / 2
|
||||
);
|
||||
this.lineBody.lineTo(
|
||||
garageConsts.bodyRectWidth / 2,
|
||||
-garageConsts.bodyRectHeight / 2
|
||||
);
|
||||
this.lineBody.moveTo(
|
||||
-garageConsts.bodyRectWidth / 2,
|
||||
garageConsts.bodyRectHeight / 2
|
||||
);
|
||||
this.lineBody.lineTo(
|
||||
garageConsts.bodyRectWidth / 2,
|
||||
garageConsts.bodyRectHeight / 2
|
||||
);
|
||||
this.lineBody.moveTo(0, -garageConsts.bodyRectHeight / 2);
|
||||
this.lineBody.lineTo(0, garageConsts.bodyRectHeight / 2);
|
||||
}
|
||||
}
|
||||
|
||||
export class GarageDoorTemplate extends JlGraphicTemplate<GarageDoor> {
|
||||
constructor(dataTemplate: IGarageDoorData) {
|
||||
super(GarageDoor.Type, { dataTemplate });
|
||||
}
|
||||
new(): GarageDoor {
|
||||
const garageDoor = new GarageDoor();
|
||||
garageDoor.loadData(this.datas);
|
||||
return garageDoor;
|
||||
}
|
||||
}
|
128
src/graphics/garageDoor/GarageDoorDrawAssistant.ts
Normal file
128
src/graphics/garageDoor/GarageDoorDrawAssistant.ts
Normal file
@ -0,0 +1,128 @@
|
||||
import { DisplayObject, FederatedMouseEvent, Point } from 'pixi.js';
|
||||
import {
|
||||
AbsorbableLine,
|
||||
AbsorbablePosition,
|
||||
GraphicDrawAssistant,
|
||||
GraphicInteractionPlugin,
|
||||
GraphicTransformEvent,
|
||||
IDrawApp,
|
||||
JlGraphic,
|
||||
} from 'jl-graphic';
|
||||
import { GarageDoor, GarageDoorTemplate, IGarageDoorData } from './GarageDoor';
|
||||
|
||||
export interface IGarageDoorDataDrawOptions {
|
||||
newData: () => IGarageDoorData;
|
||||
}
|
||||
export class GarageDoorDraw extends GraphicDrawAssistant<
|
||||
GarageDoorTemplate,
|
||||
IGarageDoorData
|
||||
> {
|
||||
_garageDoor: GarageDoor | null = null;
|
||||
constructor(app: IDrawApp, template: GarageDoorTemplate) {
|
||||
super(
|
||||
app,
|
||||
template,
|
||||
'svguse:../../drawIcon.svg#icon-flood-gate',
|
||||
'防淹门GarageDoor'
|
||||
);
|
||||
GarageDoorInteraction.init(app);
|
||||
}
|
||||
public get garageDoor(): GarageDoor {
|
||||
if (!this._garageDoor) {
|
||||
this._garageDoor = this.graphicTemplate.new();
|
||||
this._garageDoor.loadData(this.graphicTemplate.datas);
|
||||
this.container.addChild(this._garageDoor);
|
||||
}
|
||||
return this._garageDoor;
|
||||
}
|
||||
|
||||
onLeftUp(e: FederatedMouseEvent): void {
|
||||
this.container.position.copyFrom(this.toCanvasCoordinates(e.global));
|
||||
this.createAndStore(true);
|
||||
}
|
||||
|
||||
redraw(p: Point): void {
|
||||
this.garageDoor.repaint();
|
||||
this.container.position.set(p.x, p.y);
|
||||
}
|
||||
|
||||
prepareData(data: IGarageDoorData): boolean {
|
||||
data.transform = this.container.saveTransform();
|
||||
data.code = 'GarageDoor';
|
||||
return true;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 构建吸附线
|
||||
* @param garageDoor
|
||||
*/
|
||||
function buildAbsorbablePositions(
|
||||
garageDoor: GarageDoor
|
||||
): AbsorbablePosition[] {
|
||||
const aps: AbsorbablePosition[] = [];
|
||||
const garageDoors = garageDoor.queryStore.queryByType<GarageDoor>(
|
||||
GarageDoor.Type
|
||||
);
|
||||
const canvas = garageDoor.getCanvas();
|
||||
garageDoors.forEach((item) => {
|
||||
if (item.id === garageDoor.id) {
|
||||
return;
|
||||
}
|
||||
const ala = new AbsorbableLine(
|
||||
new Point(item.x, 0),
|
||||
new Point(item.x, canvas.height)
|
||||
);
|
||||
const alb = new AbsorbableLine(
|
||||
new Point(0, item.y),
|
||||
new Point(canvas.width, item.y)
|
||||
);
|
||||
aps.push(ala);
|
||||
aps.push(alb);
|
||||
});
|
||||
return aps;
|
||||
}
|
||||
|
||||
export class GarageDoorInteraction extends GraphicInteractionPlugin<GarageDoor> {
|
||||
static Name = 'garage_door_transform';
|
||||
constructor(app: IDrawApp) {
|
||||
super(GarageDoorInteraction.Name, app);
|
||||
}
|
||||
static init(app: IDrawApp) {
|
||||
return new GarageDoorInteraction(app);
|
||||
}
|
||||
filter(...grahpics: JlGraphic[]): GarageDoor[] | undefined {
|
||||
return grahpics
|
||||
.filter((g) => g.type === GarageDoor.Type)
|
||||
.map((g) => g as GarageDoor);
|
||||
}
|
||||
bind(g: GarageDoor): void {
|
||||
g.eventMode = 'static';
|
||||
g.cursor = 'pointer';
|
||||
g.scalable = true;
|
||||
g.rotatable = true;
|
||||
g.codeGraph.draggable = true;
|
||||
g.codeGraph.selectable = true;
|
||||
g.codeGraph.rotatable = true;
|
||||
g.codeGraph.transformSave = true;
|
||||
g.codeGraph.eventMode = 'static';
|
||||
g.on('transformstart', this.transformstart, this);
|
||||
}
|
||||
unbind(g: GarageDoor): void {
|
||||
g.eventMode = 'none';
|
||||
g.scalable = false;
|
||||
g.rotatable = false;
|
||||
g.codeGraph.draggable = false;
|
||||
g.codeGraph.selectable = false;
|
||||
g.codeGraph.rotatable = false;
|
||||
g.codeGraph.transformSave = false;
|
||||
g.codeGraph.eventMode = 'none';
|
||||
g.off('transformstart', this.transformstart, this);
|
||||
}
|
||||
transformstart(e: GraphicTransformEvent) {
|
||||
const target = e.target as DisplayObject;
|
||||
const garageDoor = target.getGraphic() as GarageDoor;
|
||||
garageDoor.getGraphicApp().setOptions({
|
||||
absorbablePositions: buildAbsorbablePositions(garageDoor),
|
||||
});
|
||||
}
|
||||
}
|
@ -274,6 +274,9 @@ import SignalDirectionConfig from 'src/components/draw-app/properties/SignalDire
|
||||
import { distance2, JlGraphic } from 'jl-graphic';
|
||||
import { IbpBox } from 'src/graphics/ibpBox/IbpBox';
|
||||
import { PslBox } from 'src/graphics/pslBox/PslBox';
|
||||
import { CarWashing } from 'src/graphics/carWashing/CarWashing';
|
||||
import { FloodGate } from 'src/graphics/floodGate/FloodGate';
|
||||
import { GarageDoor } from 'src/graphics/garageDoor/GarageDoor';
|
||||
|
||||
const $q = useQuasar();
|
||||
const route = useRoute();
|
||||
@ -439,6 +442,9 @@ onMounted(() => {
|
||||
ConcentrationDividingLine.Type,
|
||||
IbpBox.Type,
|
||||
PslBox.Type,
|
||||
CarWashing.Type,
|
||||
FloodGate.Type,
|
||||
GarageDoor.Type,
|
||||
];
|
||||
switch (drawStore.categoryType) {
|
||||
case CategoryType.TH:
|
||||
|
Loading…
Reference in New Issue
Block a user