区段拆分 && 区段道岔联动拖动
This commit is contained in:
parent
a3c079ba48
commit
2c219da3a2
@ -1 +1 @@
|
|||||||
Subproject commit 7e4eaed0cf06d68c75cb51c30329eff5fe4d1e3f
|
Subproject commit 1f302648b5a71a82b798b77fe238c5fc6e3081b4
|
@ -110,6 +110,8 @@ module.exports = configure(function (/* ctx */) {
|
|||||||
// components: [],
|
// components: [],
|
||||||
// directives: [],
|
// directives: [],
|
||||||
|
|
||||||
|
autoImportComponentCase: 'combined',
|
||||||
|
|
||||||
// Quasar plugins
|
// Quasar plugins
|
||||||
plugins: ['Notify', 'Dialog', 'Dark', 'AppFullscreen', 'Loading'],
|
plugins: ['Notify', 'Dialog', 'Dark', 'AppFullscreen', 'Loading'],
|
||||||
},
|
},
|
||||||
|
42
src/components/draw-app/dialogs/SectionSplitDialog.vue
Normal file
42
src/components/draw-app/dialogs/SectionSplitDialog.vue
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { useDialogPluginComponent } from 'quasar';
|
||||||
|
import { ref } from 'vue';
|
||||||
|
|
||||||
|
const num = ref(3);
|
||||||
|
const dir = ref('ltr');
|
||||||
|
const dirOptions = [
|
||||||
|
{ label: '从左至右', value: 'ltr' },
|
||||||
|
{ label: '从右至左', value: 'rtl' },
|
||||||
|
];
|
||||||
|
|
||||||
|
defineEmits([...useDialogPluginComponent.emits]);
|
||||||
|
|
||||||
|
const { dialogRef, onDialogOK, onDialogCancel } = useDialogPluginComponent();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<QDialog ref="dialogRef">
|
||||||
|
<QCard>
|
||||||
|
<QCardSection> <div class="text-h6">区段拆分</div> </QCardSection>
|
||||||
|
<QCardSection> <div>请选择要拆分的数量和方向</div> </QCardSection>
|
||||||
|
<QCardSection class="q-pt-none">
|
||||||
|
<QInput type="number" dense outlined v-model="num" :min="2" :max="20" />
|
||||||
|
</QCardSection>
|
||||||
|
<QCardSection>
|
||||||
|
<QSelect v-model="dir" dense :options="dirOptions" emitValue mapOptions>
|
||||||
|
</QSelect>
|
||||||
|
</QCardSection>
|
||||||
|
<QCardActions align="right" class="text-primary">
|
||||||
|
<QBtn flat label="取消" @click="onDialogCancel" v-close-popup />
|
||||||
|
<QBtn
|
||||||
|
flat
|
||||||
|
label="确认"
|
||||||
|
@click="onDialogOK({ num: Number(num), dir })"
|
||||||
|
v-close-popup
|
||||||
|
/>
|
||||||
|
</QCardActions>
|
||||||
|
</QCard>
|
||||||
|
</QDialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped></style>
|
@ -31,16 +31,6 @@
|
|||||||
>
|
>
|
||||||
</template>
|
</template>
|
||||||
</q-field>
|
</q-field>
|
||||||
<q-input class="q-mt-lg" outlined v-model="splitNum" type="number">
|
|
||||||
<template #after>
|
|
||||||
<q-btn
|
|
||||||
:disable="sectionModel.data.sectionType !== SectionType.Physical"
|
|
||||||
color="primary"
|
|
||||||
@click="splitSection"
|
|
||||||
>拆分为逻辑区段</q-btn
|
|
||||||
>
|
|
||||||
</template>
|
|
||||||
</q-input>
|
|
||||||
</q-form>
|
</q-form>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -56,34 +46,6 @@ const drawStore = useDrawStore();
|
|||||||
|
|
||||||
const sectionModel = shallowRef(new SectionData());
|
const sectionModel = shallowRef(new SectionData());
|
||||||
|
|
||||||
const splitNum = ref(3);
|
|
||||||
|
|
||||||
function splitSection() {
|
|
||||||
const sectionData = toRaw(sectionModel.value);
|
|
||||||
const section = toRaw(drawStore.selectedGraphic as Section);
|
|
||||||
const app = drawStore.getDrawApp();
|
|
||||||
const points = section.getSplitPoints(splitNum.value);
|
|
||||||
const childIds: string[] = [];
|
|
||||||
|
|
||||||
points.forEach((ps, i) => {
|
|
||||||
const data = new SectionData();
|
|
||||||
data.points = ps.map((p) => new graphicData.Point({ x: p.x, y: p.y }));
|
|
||||||
data.id = app.drawAssistants
|
|
||||||
.find((as) => as.name === Section.name)!
|
|
||||||
.nextId();
|
|
||||||
data.code = `${sectionData.code}-${'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.charAt(
|
|
||||||
i % 26
|
|
||||||
)}`;
|
|
||||||
data.sectionType = SectionType.Logic;
|
|
||||||
const section = app.graphicTemplateMap.get(Section.name)!.new();
|
|
||||||
section?.loadData(data);
|
|
||||||
app.addGraphics(section);
|
|
||||||
childIds.push(data.id);
|
|
||||||
});
|
|
||||||
sectionData.children = childIds;
|
|
||||||
app.updateGraphicAndRecord(section, sectionData);
|
|
||||||
}
|
|
||||||
|
|
||||||
const sectionRelations = computed(() => {
|
const sectionRelations = computed(() => {
|
||||||
const section = drawStore.selectedGraphic as Section;
|
const section = drawStore.selectedGraphic as Section;
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@ import {
|
|||||||
} from '../CommonGraphics';
|
} from '../CommonGraphics';
|
||||||
import { Turnout } from '../turnout/Turnout';
|
import { Turnout } from '../turnout/Turnout';
|
||||||
import { SectionData } from 'src/drawApp/graphics/SectionInteraction';
|
import { SectionData } from 'src/drawApp/graphics/SectionInteraction';
|
||||||
|
import Vector2 from 'src/jl-graphic/math/Vector2';
|
||||||
|
|
||||||
export enum SectionType {
|
export enum SectionType {
|
||||||
Physical = 0,
|
Physical = 0,
|
||||||
@ -134,13 +135,49 @@ export class Section extends JlGraphic implements ILineGraphic {
|
|||||||
/** 获取拆分逻辑区段数据 */
|
/** 获取拆分逻辑区段数据 */
|
||||||
getSplitPoints(count: number): IPointData[][] {
|
getSplitPoints(count: number): IPointData[][] {
|
||||||
if (this.datas.points.length !== 2) {
|
if (this.datas.points.length !== 2) {
|
||||||
throw Error('多段分割待实现');
|
// throw Error('多段分割待实现');
|
||||||
|
let totalLen = 0;
|
||||||
|
const lengths: number[] = [];
|
||||||
|
for (let i = 1; i < this.datas.points.length; i++) {
|
||||||
|
const { x: x1, y: y1 } = this.datas.points[i - 1],
|
||||||
|
{ x: x2, y: y2 } = this.datas.points[i];
|
||||||
|
const len = new Vector2([x2 - x1, y2 - y1]).length();
|
||||||
|
totalLen += len;
|
||||||
|
lengths.push(len);
|
||||||
|
}
|
||||||
|
const counts = lengths.map((length) =>
|
||||||
|
Math.round((count * length) / totalLen)
|
||||||
|
);
|
||||||
|
if (counts.reduce((p, c) => p + c, 0) !== count) {
|
||||||
|
const intersection = counts.reduce((p, c) => p + c, 0) - count;
|
||||||
|
let maxCountIndex = 0,
|
||||||
|
maxCount = 0;
|
||||||
|
counts.forEach((c, i) => {
|
||||||
|
if (c > maxCount) {
|
||||||
|
maxCount = c;
|
||||||
|
maxCountIndex = i;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
counts[maxCountIndex] + intersection;
|
||||||
|
}
|
||||||
|
return counts
|
||||||
|
.map((count, i) => {
|
||||||
|
return splitLineEvenly(
|
||||||
|
this.localToCanvasPoint(this.datas.points[i]),
|
||||||
|
this.localToCanvasPoint(this.datas.points[i + 1]),
|
||||||
|
count
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.flat();
|
||||||
|
} else {
|
||||||
|
return splitLineEvenly(
|
||||||
|
this.localToCanvasPoint(this.datas.points[0]),
|
||||||
|
this.localToCanvasPoint(
|
||||||
|
this.datas.points[this.datas.points.length - 1]
|
||||||
|
),
|
||||||
|
count
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return splitLineEvenly(
|
|
||||||
this.localToCanvasPoint(this.datas.points[0]),
|
|
||||||
this.localToCanvasPoint(this.datas.points[this.datas.points.length - 1]),
|
|
||||||
count
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
buildRelation() {
|
buildRelation() {
|
||||||
|
@ -4,6 +4,7 @@ import {
|
|||||||
GraphicApp,
|
GraphicApp,
|
||||||
GraphicDrawAssistant,
|
GraphicDrawAssistant,
|
||||||
GraphicInteractionPlugin,
|
GraphicInteractionPlugin,
|
||||||
|
GraphicRelation,
|
||||||
GraphicTransform,
|
GraphicTransform,
|
||||||
GraphicTransformEvent,
|
GraphicTransformEvent,
|
||||||
JlDrawApp,
|
JlDrawApp,
|
||||||
@ -15,25 +16,37 @@ import {
|
|||||||
ISectionData,
|
ISectionData,
|
||||||
Section,
|
Section,
|
||||||
SectionConsts,
|
SectionConsts,
|
||||||
|
SectionPort,
|
||||||
SectionTemplate,
|
SectionTemplate,
|
||||||
|
SectionType,
|
||||||
} from './Section';
|
} from './Section';
|
||||||
import {
|
import {
|
||||||
DisplayObject,
|
DisplayObject,
|
||||||
FederatedMouseEvent,
|
FederatedMouseEvent,
|
||||||
Graphics,
|
Graphics,
|
||||||
IHitArea,
|
IHitArea,
|
||||||
|
IPointData,
|
||||||
Point,
|
Point,
|
||||||
} from 'pixi.js';
|
} from 'pixi.js';
|
||||||
import {
|
import {
|
||||||
IEditPointOptions,
|
IEditPointOptions,
|
||||||
ILineGraphic,
|
ILineGraphic,
|
||||||
PolylineEditPlugin,
|
PolylineEditPlugin,
|
||||||
|
addWayPoint,
|
||||||
|
clearWayPoint,
|
||||||
|
getWaypointRangeIndex,
|
||||||
} from 'src/jl-graphic/plugins/GraphicEditPlugin';
|
} from 'src/jl-graphic/plugins/GraphicEditPlugin';
|
||||||
import AbsorbablePoint, {
|
import AbsorbablePoint, {
|
||||||
AbsorbableLine,
|
AbsorbableLine,
|
||||||
AbsorbablePosition,
|
AbsorbablePosition,
|
||||||
} from 'src/jl-graphic/graphic/AbsorbablePosition';
|
} from 'src/jl-graphic/graphic/AbsorbablePosition';
|
||||||
import { Turnout } from '../turnout/Turnout';
|
import { Turnout, TurnoutPort } from '../turnout/Turnout';
|
||||||
|
import { MenuItemOptions } from 'src/jl-graphic/ui/Menu';
|
||||||
|
import { ContextMenu } from 'src/jl-graphic/ui/ContextMenu';
|
||||||
|
import { Dialog } from 'quasar';
|
||||||
|
import { SectionData } from 'src/drawApp/graphics/SectionInteraction';
|
||||||
|
import { graphicData } from 'src/protos/stationLayoutGraphics';
|
||||||
|
import SectionSplitDialog from 'src/components/draw-app/dialogs/SectionSplitDialog.vue';
|
||||||
|
|
||||||
export class SectionDraw extends GraphicDrawAssistant<
|
export class SectionDraw extends GraphicDrawAssistant<
|
||||||
SectionTemplate,
|
SectionTemplate,
|
||||||
@ -46,7 +59,7 @@ export class SectionDraw extends GraphicDrawAssistant<
|
|||||||
super(app, template, 'sym_o_timeline', '区段Section');
|
super(app, template, 'sym_o_timeline', '区段Section');
|
||||||
this.container.addChild(this.graphic);
|
this.container.addChild(this.graphic);
|
||||||
|
|
||||||
SectionPointEditPlugin.init(app);
|
SectionPointEditPlugin.init(app, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
onLeftDown(e: FederatedMouseEvent): void {
|
onLeftDown(e: FederatedMouseEvent): void {
|
||||||
@ -88,20 +101,23 @@ export class SectionDraw extends GraphicDrawAssistant<
|
|||||||
prepareData(data: ISectionData): boolean {
|
prepareData(data: ISectionData): boolean {
|
||||||
data.points = this.points;
|
data.points = this.points;
|
||||||
data.code = 'G000';
|
data.code = 'G000';
|
||||||
data.childTransforms?.push(
|
console.log(data.points[1].x);
|
||||||
|
console.log(data.points[0].x);
|
||||||
|
data.childTransforms = [
|
||||||
new ChildTransform(
|
new ChildTransform(
|
||||||
'label',
|
'label',
|
||||||
new GraphicTransform(
|
new GraphicTransform(
|
||||||
{
|
{
|
||||||
x: data.points[1].x - data.points[0].x,
|
x: data.points[0].x + (data.points[1].x - data.points[0].x) / 2,
|
||||||
y: data.points[1].y - data.points[0].y + 20,
|
y:
|
||||||
|
data.points[0].y + (data.points[1].y - data.points[0].y) / 2 + 20,
|
||||||
},
|
},
|
||||||
{ x: 0, y: 0 },
|
{ x: 0, y: 0 },
|
||||||
0,
|
0,
|
||||||
{ x: 0, y: 0 }
|
{ x: 0, y: 0 }
|
||||||
)
|
)
|
||||||
)
|
),
|
||||||
);
|
];
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -191,9 +207,71 @@ class SectionPolylineEditPlugin extends PolylineEditPlugin {
|
|||||||
this.updateEditedPointsPosition();
|
this.updateEditedPointsPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
reset(): void {
|
setRelatedDrag() {
|
||||||
super.reset();
|
const len = this.editedPoints.length;
|
||||||
this.initLabels();
|
this.editedPoints.forEach((ep, i) => {
|
||||||
|
if (i === 0 || i === len - 1) {
|
||||||
|
let relations: GraphicRelation[];
|
||||||
|
if (i === 0) {
|
||||||
|
relations = this.graphic.relationManage
|
||||||
|
.getRelationsOfGraphic(this.graphic)
|
||||||
|
.filter(
|
||||||
|
(relation) =>
|
||||||
|
relation.getRelationParam(this.graphic).param === SectionPort.A
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
relations = this.graphic.relationManage
|
||||||
|
.getRelationsOfGraphic(this.graphic)
|
||||||
|
.filter(
|
||||||
|
(relation) =>
|
||||||
|
relation.getRelationParam(this.graphic).param === SectionPort.B
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (!relations.length) return;
|
||||||
|
const points: IPointData[] = [];
|
||||||
|
const otherGraphics = relations.map((relation) =>
|
||||||
|
relation.getOtherGraphic(this.graphic)
|
||||||
|
);
|
||||||
|
const otherPorts = relations.map(
|
||||||
|
(relation) => relation.getOtherRelationParam(this.graphic).param
|
||||||
|
);
|
||||||
|
otherGraphics.forEach((otherGraphic, i) => {
|
||||||
|
const otherPort = otherPorts[i];
|
||||||
|
if (otherGraphic instanceof Turnout) {
|
||||||
|
if (otherPort === TurnoutPort.A) {
|
||||||
|
points.push(
|
||||||
|
otherGraphic.datas.pointA[otherGraphic.datas.pointA.length - 1]
|
||||||
|
);
|
||||||
|
} else if (otherPort === TurnoutPort.B) {
|
||||||
|
points.push(
|
||||||
|
otherGraphic.datas.pointB[otherGraphic.datas.pointB.length - 1]
|
||||||
|
);
|
||||||
|
} else if (otherPort === TurnoutPort.C) {
|
||||||
|
points.push(
|
||||||
|
otherGraphic.datas.pointC[otherGraphic.datas.pointC.length - 1]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else if (otherGraphic instanceof Section) {
|
||||||
|
if (otherPort === SectionPort.A) {
|
||||||
|
points.push(otherGraphic.datas.points[0]);
|
||||||
|
} else if (otherPort === SectionPort.B) {
|
||||||
|
points.push(
|
||||||
|
otherGraphic.datas.points[otherGraphic.datas.points.length - 1]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const transformingHandler = () => {
|
||||||
|
otherGraphics.forEach((otherGraphic, i) => {
|
||||||
|
const p = otherGraphic.canvasToLocalPoint(ep);
|
||||||
|
points[i].x = p.x;
|
||||||
|
points[i].y = p.y;
|
||||||
|
otherGraphic.repaint();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
ep.on('transforming', transformingHandler);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
updateEditedPointsPosition() {
|
updateEditedPointsPosition() {
|
||||||
@ -209,14 +287,39 @@ class SectionPolylineEditPlugin extends PolylineEditPlugin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const addWaypointConfig: MenuItemOptions = {
|
||||||
|
name: '添加路径点',
|
||||||
|
};
|
||||||
|
export const clearWaypointsConfig: MenuItemOptions = {
|
||||||
|
name: '清除所有路径点',
|
||||||
|
};
|
||||||
|
export const splitSectionConfig: MenuItemOptions = {
|
||||||
|
name: '拆分',
|
||||||
|
// disabled: true,
|
||||||
|
};
|
||||||
|
const SectionEditMenu: ContextMenu = ContextMenu.init({
|
||||||
|
name: '区段编辑菜单',
|
||||||
|
groups: [
|
||||||
|
{
|
||||||
|
items: [addWaypointConfig, clearWaypointsConfig],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
items: [splitSectionConfig],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
export class SectionPointEditPlugin extends GraphicInteractionPlugin<Section> {
|
export class SectionPointEditPlugin extends GraphicInteractionPlugin<Section> {
|
||||||
static Name = 'SectionPointDrag';
|
static Name = 'SectionPointDrag';
|
||||||
|
drawAssistant: SectionDraw;
|
||||||
|
|
||||||
constructor(app: GraphicApp) {
|
constructor(app: GraphicApp, da: SectionDraw) {
|
||||||
super(SectionPointEditPlugin.Name, app);
|
super(SectionPointEditPlugin.Name, app);
|
||||||
|
this.drawAssistant = da;
|
||||||
|
app.registerMenu(SectionEditMenu);
|
||||||
}
|
}
|
||||||
static init(app: GraphicApp) {
|
static init(app: GraphicApp, da: SectionDraw) {
|
||||||
return new SectionPointEditPlugin(app);
|
return new SectionPointEditPlugin(app, da);
|
||||||
}
|
}
|
||||||
filter(...grahpics: JlGraphic[]): Section[] | undefined {
|
filter(...grahpics: JlGraphic[]): Section[] | undefined {
|
||||||
return grahpics.filter((g) => g.type == Section.Type) as Section[];
|
return grahpics.filter((g) => g.type == Section.Type) as Section[];
|
||||||
@ -232,14 +335,99 @@ export class SectionPointEditPlugin extends GraphicInteractionPlugin<Section> {
|
|||||||
g.labelGraphic.draggable = true;
|
g.labelGraphic.draggable = true;
|
||||||
g.on('selected', this.onSelected, this);
|
g.on('selected', this.onSelected, this);
|
||||||
g.on('unselected', this.onUnselected, this);
|
g.on('unselected', this.onUnselected, this);
|
||||||
|
g.on('_rightclick', this.onContextMenu, this);
|
||||||
}
|
}
|
||||||
unbind(g: Section): void {
|
unbind(g: Section): void {
|
||||||
g.off('selected', this.onSelected, this);
|
g.off('selected', this.onSelected, this);
|
||||||
g.off('unselected', this.onUnselected, this);
|
g.off('unselected', this.onUnselected, this);
|
||||||
|
g.off('_rightclick', this.onContextMenu, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
onContextMenu(e: FederatedMouseEvent) {
|
||||||
|
const target = e.target as DisplayObject;
|
||||||
|
const section = target.getGraphic() as Section;
|
||||||
|
this.app.updateSelected(section);
|
||||||
|
const p = section.screenToLocalPoint(e.global);
|
||||||
|
|
||||||
|
addWaypointConfig.handler = () => {
|
||||||
|
const linePoints = section.linePoints;
|
||||||
|
const { start, end } = getWaypointRangeIndex(
|
||||||
|
linePoints,
|
||||||
|
false,
|
||||||
|
p,
|
||||||
|
SectionConsts.lineWidth
|
||||||
|
);
|
||||||
|
addWayPoint(section, false, start, end, p);
|
||||||
|
};
|
||||||
|
clearWaypointsConfig.handler = () => {
|
||||||
|
clearWayPoint(section, false);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (
|
||||||
|
section.datas.children &&
|
||||||
|
section.datas.sectionType === SectionType.Physical
|
||||||
|
) {
|
||||||
|
splitSectionConfig.disabled = false;
|
||||||
|
splitSectionConfig.handler = () => {
|
||||||
|
Dialog.create({
|
||||||
|
title: '拆分区段',
|
||||||
|
message: '请选择生成数量和方向',
|
||||||
|
component: SectionSplitDialog,
|
||||||
|
cancel: true,
|
||||||
|
persistent: true,
|
||||||
|
}).onOk((data: { num: number; dir: 'ltr' | 'rtl' }) => {
|
||||||
|
const { num, dir } = data;
|
||||||
|
const sectionData = section.datas;
|
||||||
|
const points = section.getSplitPoints(num);
|
||||||
|
const children: Section[] = [];
|
||||||
|
let codeAppend = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.slice(0, num);
|
||||||
|
if (
|
||||||
|
(dir === 'ltr' &&
|
||||||
|
sectionData.points[0].x >
|
||||||
|
sectionData.points[sectionData.points.length - 1].x) ||
|
||||||
|
(dir === 'rtl' &&
|
||||||
|
sectionData.points[0].x <
|
||||||
|
sectionData.points[sectionData.points.length - 1].x)
|
||||||
|
) {
|
||||||
|
codeAppend = codeAppend.split('').reverse().join('');
|
||||||
|
}
|
||||||
|
points.forEach((ps, i) => {
|
||||||
|
const data = new SectionData();
|
||||||
|
data.id = this.drawAssistant.nextId();
|
||||||
|
data.code = `${sectionData.code}-${codeAppend.charAt(i % 26)}`;
|
||||||
|
data.sectionType = SectionType.Logic;
|
||||||
|
data.points = ps.map(
|
||||||
|
(p) => new graphicData.Point({ x: p.x, y: p.y })
|
||||||
|
);
|
||||||
|
data.id = this.drawAssistant.nextId();
|
||||||
|
const g = this.drawAssistant.graphicTemplate.new();
|
||||||
|
g.loadData(data);
|
||||||
|
this.drawAssistant.storeGraphic(g);
|
||||||
|
children.push(g);
|
||||||
|
});
|
||||||
|
sectionData.children = children.map((g) => g.datas.id);
|
||||||
|
section.repaint();
|
||||||
|
section.buildRelation();
|
||||||
|
section.draggable = false;
|
||||||
|
children.forEach((c) => c.buildRelation());
|
||||||
|
this.app.updateSelected(...children);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
splitSectionConfig.disabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
SectionEditMenu.open(e.global);
|
||||||
}
|
}
|
||||||
|
|
||||||
onSelected(g: DisplayObject): void {
|
onSelected(g: DisplayObject): void {
|
||||||
const section = g as Section;
|
const section = g as Section;
|
||||||
|
if (
|
||||||
|
section.datas.children.length > 0 &&
|
||||||
|
section.datas.sectionType === SectionType.Physical
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
let lep = section.getAssistantAppend<SectionPolylineEditPlugin>(
|
let lep = section.getAssistantAppend<SectionPolylineEditPlugin>(
|
||||||
SectionPolylineEditPlugin.Name
|
SectionPolylineEditPlugin.Name
|
||||||
);
|
);
|
||||||
@ -248,6 +436,7 @@ export class SectionPointEditPlugin extends GraphicInteractionPlugin<Section> {
|
|||||||
section.addAssistantAppend(lep);
|
section.addAssistantAppend(lep);
|
||||||
}
|
}
|
||||||
lep.showAll();
|
lep.showAll();
|
||||||
|
lep.setRelatedDrag();
|
||||||
}
|
}
|
||||||
onUnselected(g: DisplayObject): void {
|
onUnselected(g: DisplayObject): void {
|
||||||
const section = g as Section;
|
const section = g as Section;
|
||||||
|
@ -4,6 +4,7 @@ import {
|
|||||||
GraphicApp,
|
GraphicApp,
|
||||||
GraphicDrawAssistant,
|
GraphicDrawAssistant,
|
||||||
GraphicInteractionPlugin,
|
GraphicInteractionPlugin,
|
||||||
|
GraphicRelation,
|
||||||
GraphicTransformEvent,
|
GraphicTransformEvent,
|
||||||
JlDrawApp,
|
JlDrawApp,
|
||||||
JlGraphic,
|
JlGraphic,
|
||||||
@ -31,7 +32,7 @@ import {
|
|||||||
GraphicEditPlugin,
|
GraphicEditPlugin,
|
||||||
getWaypointRangeIndex,
|
getWaypointRangeIndex,
|
||||||
} from 'src/jl-graphic/plugins/GraphicEditPlugin';
|
} from 'src/jl-graphic/plugins/GraphicEditPlugin';
|
||||||
import { Section } from '../section/Section';
|
import { Section, SectionPort } from '../section/Section';
|
||||||
import AbsorbablePoint, {
|
import AbsorbablePoint, {
|
||||||
AbsorbableLine,
|
AbsorbableLine,
|
||||||
} from 'src/jl-graphic/graphic/AbsorbablePosition';
|
} from 'src/jl-graphic/graphic/AbsorbablePosition';
|
||||||
@ -338,8 +339,9 @@ export class TurnoutPointsInteractionPlugin extends GraphicInteractionPlugin<Tur
|
|||||||
tep = new TurnoutEditPlugin(turnout, { onEditPointCreate });
|
tep = new TurnoutEditPlugin(turnout, { onEditPointCreate });
|
||||||
turnout.addAssistantAppend(tep);
|
turnout.addAssistantAppend(tep);
|
||||||
}
|
}
|
||||||
tep.reset();
|
// tep.reset();
|
||||||
tep.showAll();
|
tep.showAll();
|
||||||
|
tep.setRelatedDrag();
|
||||||
}
|
}
|
||||||
|
|
||||||
onUnSelected(g: DisplayObject) {
|
onUnSelected(g: DisplayObject) {
|
||||||
@ -380,6 +382,82 @@ export class TurnoutEditPlugin extends GraphicEditPlugin<Turnout> {
|
|||||||
this.removeChildren();
|
this.removeChildren();
|
||||||
this.initEditPoints();
|
this.initEditPoints();
|
||||||
}
|
}
|
||||||
|
hideAll(): void {
|
||||||
|
super.hideAll();
|
||||||
|
}
|
||||||
|
setRelatedDrag() {
|
||||||
|
this.editPoints.forEach((eps, i) => {
|
||||||
|
const ep = eps[eps.length - 1];
|
||||||
|
let relations: GraphicRelation[];
|
||||||
|
if (i === 0) {
|
||||||
|
relations = this.graphic.relationManage
|
||||||
|
.getRelationsOfGraphic(this.graphic)
|
||||||
|
.filter(
|
||||||
|
(relation) =>
|
||||||
|
relation.getRelationParam(this.graphic).param === TurnoutPort.A
|
||||||
|
);
|
||||||
|
} else if (i === 1) {
|
||||||
|
relations = this.graphic.relationManage
|
||||||
|
.getRelationsOfGraphic(this.graphic)
|
||||||
|
.filter(
|
||||||
|
(relation) =>
|
||||||
|
relation.getRelationParam(this.graphic).param === TurnoutPort.B
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
relations = this.graphic.relationManage
|
||||||
|
.getRelationsOfGraphic(this.graphic)
|
||||||
|
.filter(
|
||||||
|
(relation) =>
|
||||||
|
relation.getRelationParam(this.graphic).param === TurnoutPort.C
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (!relations.length) return;
|
||||||
|
const otherGraphics = relations.map((relation) =>
|
||||||
|
relation.getOtherGraphic(this.graphic)
|
||||||
|
);
|
||||||
|
console.log(otherGraphics);
|
||||||
|
const otherPorts = relations.map(
|
||||||
|
(relation) => relation.getOtherRelationParam(this.graphic).param
|
||||||
|
);
|
||||||
|
|
||||||
|
const point: IPointData[] = [];
|
||||||
|
otherGraphics.map((otherGraphic, i) => {
|
||||||
|
const otherPort = otherPorts[i];
|
||||||
|
if (otherGraphic instanceof Turnout) {
|
||||||
|
if (otherPort === TurnoutPort.A) {
|
||||||
|
point.push(
|
||||||
|
otherGraphic.datas.pointA[otherGraphic.datas.pointA.length - 1]
|
||||||
|
);
|
||||||
|
} else if (otherPort === TurnoutPort.B) {
|
||||||
|
point.push(
|
||||||
|
otherGraphic.datas.pointB[otherGraphic.datas.pointB.length - 1]
|
||||||
|
);
|
||||||
|
} else if (otherPort === TurnoutPort.C) {
|
||||||
|
point.push(
|
||||||
|
otherGraphic.datas.pointC[otherGraphic.datas.pointC.length - 1]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else if (otherGraphic instanceof Section) {
|
||||||
|
if (otherPort === SectionPort.A) {
|
||||||
|
point.push(otherGraphic.datas.points[0]);
|
||||||
|
} else if (otherPort === SectionPort.B) {
|
||||||
|
point.push(
|
||||||
|
otherGraphic.datas.points[otherGraphic.datas.points.length - 1]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const transformingHandler = () => {
|
||||||
|
otherGraphics.forEach((otherGraphic, i) => {
|
||||||
|
const p = otherGraphic.canvasToLocalPoint(ep);
|
||||||
|
point[i].x = p.x;
|
||||||
|
point[i].y = p.y;
|
||||||
|
otherGraphic.repaint();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
ep.on('transforming', transformingHandler);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
initEditPoints() {
|
initEditPoints() {
|
||||||
const cpA = this.graphic.localToCanvasPoints(...this.graphic.datas.pointA);
|
const cpA = this.graphic.localToCanvasPoints(...this.graphic.datas.pointA);
|
||||||
|
@ -32,13 +32,13 @@ export abstract class GraphicEditPlugin<
|
|||||||
this.sortableChildren = true;
|
this.sortableChildren = true;
|
||||||
this.graphic.on('transformstart', this.hideAll, this);
|
this.graphic.on('transformstart', this.hideAll, this);
|
||||||
this.graphic.on('transformend', this.showAll, this);
|
this.graphic.on('transformend', this.showAll, this);
|
||||||
this.graphic.on('repaint', this.showAll, this);
|
this.graphic.on('repaint', this.updateEditedPointsPosition, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
destroy(options?: boolean | IDestroyOptions | undefined): void {
|
destroy(options?: boolean | IDestroyOptions | undefined): void {
|
||||||
this.graphic.off('transformstart', this.hideAll, this);
|
this.graphic.off('transformstart', this.hideAll, this);
|
||||||
this.graphic.off('transformend', this.showAll, this);
|
this.graphic.off('transformend', this.showAll, this);
|
||||||
this.graphic.off('repaint', this.showAll, this);
|
this.graphic.off('repaint', this.updateEditedPointsPosition, this);
|
||||||
super.destroy(options);
|
super.destroy(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,7 +188,7 @@ export namespace state {
|
|||||||
return Section.deserialize(bytes);
|
return Section.deserialize(bytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export class Switch extends pb_1.Message {
|
export class Turnout extends pb_1.Message {
|
||||||
#one_of_decls: number[][] = [];
|
#one_of_decls: number[][] = [];
|
||||||
constructor(data?: any[] | {
|
constructor(data?: any[] | {
|
||||||
id?: string;
|
id?: string;
|
||||||
@ -242,8 +242,8 @@ export namespace state {
|
|||||||
code?: string;
|
code?: string;
|
||||||
kilometerSystem?: ReturnType<typeof dependency_1.graphicData.KilometerSystem.prototype.toObject>[];
|
kilometerSystem?: ReturnType<typeof dependency_1.graphicData.KilometerSystem.prototype.toObject>[];
|
||||||
convertKilometer?: number[];
|
convertKilometer?: number[];
|
||||||
}): Switch {
|
}): Turnout {
|
||||||
const message = new Switch({});
|
const message = new Turnout({});
|
||||||
if (data.id != null) {
|
if (data.id != null) {
|
||||||
message.id = data.id;
|
message.id = data.id;
|
||||||
}
|
}
|
||||||
@ -294,8 +294,8 @@ export namespace state {
|
|||||||
if (!w)
|
if (!w)
|
||||||
return writer.getResultBuffer();
|
return writer.getResultBuffer();
|
||||||
}
|
}
|
||||||
static deserialize(bytes: Uint8Array | pb_1.BinaryReader): Switch {
|
static deserialize(bytes: Uint8Array | pb_1.BinaryReader): Turnout {
|
||||||
const reader = bytes instanceof pb_1.BinaryReader ? bytes : new pb_1.BinaryReader(bytes), message = new Switch();
|
const reader = bytes instanceof pb_1.BinaryReader ? bytes : new pb_1.BinaryReader(bytes), message = new Turnout();
|
||||||
while (reader.nextField()) {
|
while (reader.nextField()) {
|
||||||
if (reader.isEndGroup())
|
if (reader.isEndGroup())
|
||||||
break;
|
break;
|
||||||
@ -320,8 +320,8 @@ export namespace state {
|
|||||||
serializeBinary(): Uint8Array {
|
serializeBinary(): Uint8Array {
|
||||||
return this.serialize();
|
return this.serialize();
|
||||||
}
|
}
|
||||||
static deserializeBinary(bytes: Uint8Array): Switch {
|
static deserializeBinary(bytes: Uint8Array): Turnout {
|
||||||
return Switch.deserialize(bytes);
|
return Turnout.deserialize(bytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 549aa2ec10bffe292a1a68e278ae824a8502db0b
|
Subproject commit 8fd000d45907f94410786c3bd6c1ab37edbe91e8
|
Loading…
Reference in New Issue
Block a user