2023-01-17 18:32:15 +00:00
|
|
|
<template>
|
|
|
|
<PlannerSidebar title="Layers">
|
2023-01-18 17:00:51 +00:00
|
|
|
<div class="bg-white-50 flex h-full flex-col overflow-auto">
|
2023-01-17 18:32:15 +00:00
|
|
|
<template v-for="layer of layers">
|
|
|
|
<button
|
2023-01-18 18:47:22 +00:00
|
|
|
@click="emit('selectLayer', layer.id)"
|
2023-01-17 18:32:15 +00:00
|
|
|
:class="[
|
|
|
|
layer.active ? 'bg-blue-50' : '',
|
|
|
|
'flex w-full flex-row items-center justify-start space-x-2 px-2 py-2',
|
|
|
|
]"
|
|
|
|
>
|
|
|
|
<Square3Stack3DIcon class="h-4 w-4" />
|
2023-01-18 18:47:22 +00:00
|
|
|
<span>{{ layer.name }}</span>
|
2023-01-17 18:32:15 +00:00
|
|
|
</button>
|
|
|
|
<div class="flex flex-col bg-gray-50" v-if="layer.active">
|
|
|
|
<div v-for="object of layer.contents">
|
|
|
|
<button
|
|
|
|
@dblclick="editingObjectName = object.id"
|
|
|
|
@click="
|
|
|
|
(e) =>
|
|
|
|
!editingObjectName &&
|
|
|
|
emit('selectObject', layer.id, object.id, e.shiftKey)
|
|
|
|
"
|
|
|
|
:class="[
|
2023-01-18 18:47:22 +00:00
|
|
|
object.selected
|
|
|
|
? 'bg-blue-100 hover:bg-blue-200'
|
|
|
|
: 'hover:bg-gray-100',
|
|
|
|
!object.visible ? 'italic text-gray-500' : '',
|
2023-01-17 18:32:15 +00:00
|
|
|
'flex w-full flex-row items-center justify-start space-x-2 px-2 py-2 pl-6',
|
|
|
|
]"
|
|
|
|
>
|
|
|
|
<component :is="objectTypeIcons[object.type]" class="h-4 w-4" />
|
|
|
|
<input
|
|
|
|
v-model="object.name"
|
|
|
|
v-if="editingObjectName === object.id"
|
|
|
|
@blur="commitObjectName(layer.id, object.name)"
|
|
|
|
@keypress.enter="commitObjectName(layer.id, object.name)"
|
|
|
|
/>
|
|
|
|
<span v-else>{{ object.name }}</span>
|
|
|
|
</button>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
</div>
|
|
|
|
</PlannerSidebar>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
|
import {
|
|
|
|
PencilSquareIcon,
|
|
|
|
PencilIcon,
|
|
|
|
HomeIcon,
|
|
|
|
ArrowDownOnSquareIcon,
|
|
|
|
Square3Stack3DIcon,
|
|
|
|
} from '@heroicons/vue/24/outline';
|
|
|
|
import type { Component } from 'vue';
|
|
|
|
import { ref } from 'vue';
|
|
|
|
import PlannerSidebar from './PlannerSidebar.vue';
|
|
|
|
import { Layer } from '../../modules/house-planner/interfaces';
|
|
|
|
import { LayerObjectType } from '../../modules/house-planner/types';
|
|
|
|
|
|
|
|
const objectTypeIcons: Record<LayerObjectType, Component> = {
|
|
|
|
line: PencilIcon,
|
|
|
|
room: HomeIcon,
|
|
|
|
curve: ArrowDownOnSquareIcon,
|
|
|
|
object: PencilSquareIcon,
|
|
|
|
};
|
|
|
|
|
|
|
|
const props = defineProps<{
|
|
|
|
layers: Layer[];
|
|
|
|
}>();
|
|
|
|
|
|
|
|
const emit = defineEmits<{
|
|
|
|
(e: 'layerName', layer: number, name: string): void;
|
|
|
|
(e: 'objectName', layer: number, object: number, name: string): void;
|
|
|
|
(e: 'selectLayer', layer: number): void;
|
|
|
|
(e: 'selectObject', layer: number, object: number, add?: boolean): void;
|
|
|
|
}>();
|
|
|
|
|
|
|
|
const editingObjectName = ref<number | null>(null);
|
|
|
|
|
|
|
|
const commitObjectName = (layerId: number, name: string) => {
|
|
|
|
if (editingObjectName.value == null) return;
|
|
|
|
emit('objectName', layerId, editingObjectName.value, name);
|
|
|
|
editingObjectName.value = null;
|
|
|
|
};
|
|
|
|
</script>
|