Added better rail systems list.

This commit is contained in:
Andrew Lalis 2022-05-20 23:30:57 +02:00
parent ee165f6d8b
commit b5bcdc12e1
6 changed files with 204 additions and 24 deletions

View File

@ -0,0 +1,39 @@
<template>
<q-list>
<q-item-label header>Rail Systems</q-item-label>
<rail-system-link
v-for="rs in railSystems"
:key="rs.id"
:rail-system="rs"
/>
<q-item>
<q-input
dense
type="text"
label="Name"
/>
<q-btn label="Add" color="primary"></q-btn>
</q-item>
</q-list>
</template>
<script>
import RailSystemLink from "components/RailSystemLink.vue";
export default {
name: "RailSystemsList",
components: { RailSystemLink },
props: {
railSystems: {
type: Array,
required: true
}
}
};
</script>
<style scoped>
</style>

View File

@ -1,14 +1,12 @@
<template>
<div class="row bg-green-4">
<div class="col-md-8 bg-blue-2" id="railSystemMapCanvasContainer">
<div class="row">
<div class="col-md-8" id="railSystemMapCanvasContainer">
<canvas id="railSystemMapCanvas" height="800">
Your browser doesn't support canvas.
</canvas>
</div>
<div class="col-md-4 bg-amber">
<p>
Info panel
</p>
<div class="col-md-4" v-if="railSystem.selectedComponent">
<selected-component-view :component="railSystem.selectedComponent" />
</div>
</div>
@ -17,9 +15,11 @@
<script>
import { RailSystem } from "src/api/railSystems";
import { draw, initMap } from "src/render/mapRenderer";
import SelectedComponentView from "components/rs/SelectedComponentView.vue";
export default {
name: "MapView",
components: { SelectedComponentView },
props: {
railSystem: {
type: RailSystem,

View File

@ -1,12 +1,153 @@
<template>
<div class="q-pa-md">
<div class="text-h6">{{component.name}}</div>
<q-list bordered>
<q-item clickable>
<q-item-section>
<q-item-label>{{component.type}}</q-item-label>
<q-item-label caption>Id: {{component.id}}</q-item-label>
</q-item-section>
</q-item>
<q-item clickable>
<q-item-section>
<q-item-label>Position</q-item-label>
<q-item-label caption>
X: {{component.position.x}},
Y: {{component.position.y}},
Z: {{component.position.z}}
</q-item-label>
</q-item-section>
</q-item>
<!-- Signal info -->
<q-expansion-item
id="signalInfo"
label="Signal Information"
v-if="component.type === 'SIGNAL'"
content-inset-level="0.5"
switch-toggle-side
expand-separator
>
<q-list>
<q-item
v-for="segment in [component.segment]"
:key="segment.id"
clickable
v-ripple
>
<q-item-section>
<q-item-label>Linked to segment: {{segment.name}}</q-item-label>
<q-item-label caption>Id: {{segment.id}}</q-item-label>
</q-item-section>
</q-item>
</q-list>
</q-expansion-item>
<!-- Path node info -->
<q-expansion-item
label="Path Node Information"
v-if="component.connectedNodes !== undefined && component.connectedNodes !== null"
content-inset-level="0.5"
switch-toggle-side
expand-separator
>
<q-list>
<q-item
v-for="node in component.connectedNodes"
:key="node.id"
clickable
v-ripple
@click="select(node)"
>
<q-item-section>
<q-item-label>{{node.name}}</q-item-label>
<q-item-label caption>Id: {{node.id}}</q-item-label>
</q-item-section>
</q-item>
</q-list>
</q-expansion-item>
<!-- Segment boundary info -->
<q-expansion-item
label="Segment Boundary Information"
v-if="component.type === 'SEGMENT_BOUNDARY'"
content-inset-level="0.5"
switch-toggle-side
expand-separator
>
<q-list>
<q-item
v-for="segment in component.segments"
:key="segment.id"
clickable
v-ripple
>
<q-item-section>
<q-item-label>{{segment.name}}</q-item-label>
<q-item-label caption>Id: {{segment.id}}</q-item-label>
</q-item-section>
</q-item>
</q-list>
</q-expansion-item>
<!-- Switch info -->
<q-expansion-item
label="Switch Information"
v-if="component.type === 'SWITCH'"
content-inset-level="0.5"
switch-toggle-side
expand-separator
>
<q-list>
<q-item
v-for="config in component.possibleConfigurations"
:key="config.id"
>
<q-item-section>
<q-item-label class="q-gutter-md">
<q-btn
v-for="node in config.nodes"
:key="node.id"
dense
size="sm"
:label="node.name"
:color="component.activeConfiguration && component.activeConfiguration.id === config.id ? 'primary' : 'secondary'"
@click="select(node)"
/>
</q-item-label>
</q-item-section>
</q-item>
</q-list>
</q-expansion-item>
</q-list>
</div>
</template>
<script>
import { RailSystem } from "src/api/railSystems";
import { useRailSystemsStore } from "stores/railSystemsStore";
export default {
name: "SelectedComponentView"
name: "SelectedComponentView",
setup() {
const rsStore = useRailSystemsStore();
return {rsStore};
},
props: {
component: {
type: Object,
required: true
}
},
methods: {
select(component) {
const c = this.rsStore.selectedRailSystem.components.find(cp => cp.id === component.id);
if (c) {
this.rsStore.selectedRailSystem.selectedComponent = c;
}
}
}
};
</script>

View File

@ -25,15 +25,7 @@
show-if-above
bordered
>
<q-list>
<q-item-label header>Rail Systems</q-item-label>
<rail-system-link
v-for="rs in rsStore.railSystems"
:key="rs.id"
:rail-system="rs"
/>
</q-list>
<rail-systems-list :rail-systems="rsStore.railSystems" />
</q-drawer>
<q-page-container>
@ -44,17 +36,15 @@
<script>
import { defineComponent, ref } from "vue";
import RailSystemLink from "components/RailSystemLink.vue";
import RailSystemsList from "components/RailSystemsList.vue";
import { useRailSystemsStore } from "stores/railSystemsStore";
import { refreshRailSystems } from "src/api/railSystems";
export default defineComponent({
name: 'MainLayout',
components: {
RailSystemLink
RailSystemsList
},
setup () {
const rsStore = useRailSystemsStore()
const leftDrawerOpen = ref(false)

View File

@ -2,8 +2,8 @@
Helper functions to actually perform rendering of different components.
*/
import {getScaleFactor, isComponentHovered} from "./mapRenderer";
import {roundedRect, circle} from "./canvasUtils";
import { getScaleFactor, isComponentHovered, isComponentSelected } from "./mapRenderer";
import { circle, roundedRect } from "./canvasUtils";
export function drawComponent(ctx, worldTx, component) {
const tx = DOMMatrix.fromMatrix(worldTx);
@ -28,7 +28,7 @@ export function drawComponent(ctx, worldTx, component) {
ctx.setTransform(tx);
// Draw hovered status.
if (isComponentHovered(component)) {
if (isComponentHovered(component) || isComponentSelected(component)) {
ctx.fillStyle = `rgba(255, 255, 0, 0.5)`;
circle(ctx, 0, 0, 0.75);
ctx.fill();

View File

@ -129,6 +129,10 @@ export function getScaleFactor() {
return SCALE_VALUES[mapScaleIndex];
}
/**
* Gets a matrix that transforms world coordinates to canvas.
* @returns {DOMMatrix}
*/
function getWorldTransform() {
const canvasRect = mapCanvas.getBoundingClientRect();
const scale = getScaleFactor();
@ -149,6 +153,10 @@ export function isComponentHovered(component) {
return false;
}
export function isComponentSelected(component) {
return railSystem.selectedComponent !== null && railSystem.selectedComponent.id === component.id;
}
/**
* Maps a point on the map coordinates to world coordinates.
* @param {DOMPoint} p
@ -195,13 +203,15 @@ function onMouseDown(event) {
}
function onMouseUp() {
let finishedDrag = false;
if (mapDragTranslation !== null) {
mapTranslation.x += mapDragTranslation.x;
mapTranslation.y += mapDragTranslation.y;
finishedDrag = true;
}
if (hoveredElements.length === 1) {
railSystem.selectedComponent = hoveredElements[0];
} else {
} else if (!finishedDrag) {
railSystem.selectedComponent = null;
}
mapDragOrigin = null;