149 lines
3.4 KiB
Vue
149 lines
3.4 KiB
Vue
<template>
|
|
<PlannerSidebar :title="$t('planner.panel.properties.title')">
|
|
<div
|
|
class="bg-white-50 flex h-full flex-col overflow-auto"
|
|
v-if="selectedObject && applicableProperties"
|
|
>
|
|
<PropertyFormItem
|
|
v-for="prop of applicableProperties.properties"
|
|
:id="selectedObject.id"
|
|
:prop="prop"
|
|
:value="selectedObject[prop.key as keyof typeof selectedObject]"
|
|
@update="(newValue) => updateProp(prop, newValue)"
|
|
/>
|
|
</div>
|
|
</PlannerSidebar>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import PlannerSidebar from './PlannerSidebar.vue';
|
|
import { Layer } from '../../modules/house-planner/interfaces';
|
|
import {
|
|
ObjectProperties,
|
|
ObjectProperty,
|
|
} from './interfaces/properties.interfaces';
|
|
import { computed } from 'vue';
|
|
import PropertyFormItem from './PropertyFormItem.vue';
|
|
import { useI18n } from 'vue-i18n';
|
|
|
|
const { t } = useI18n();
|
|
|
|
const props = defineProps<{
|
|
layers: Layer[];
|
|
}>();
|
|
|
|
const emit = defineEmits<{
|
|
(
|
|
e: 'update',
|
|
layerId: number,
|
|
objectId: number,
|
|
key: string,
|
|
value: unknown,
|
|
): void;
|
|
}>();
|
|
|
|
const commonProps: ObjectProperty[] = [
|
|
{ key: 'name', title: t('planner.properties.name'), type: 'string' },
|
|
{
|
|
key: 'visible',
|
|
title: t('planner.properties.visible'),
|
|
type: 'boolean',
|
|
groupable: true,
|
|
},
|
|
];
|
|
|
|
const lineProps: ObjectProperty[] = [
|
|
...commonProps,
|
|
{
|
|
key: 'width',
|
|
title: t('planner.properties.width'),
|
|
type: 'number',
|
|
groupable: true,
|
|
},
|
|
{
|
|
key: 'color',
|
|
title: t('planner.properties.color'),
|
|
type: 'color',
|
|
groupable: true,
|
|
},
|
|
{
|
|
key: 'lineCap',
|
|
title: t('planner.properties.lineCap'),
|
|
type: 'select',
|
|
groupable: true,
|
|
options: [
|
|
{ value: undefined, title: '' },
|
|
{ value: 'butt', title: t('planner.properties.butt') },
|
|
{ value: 'round', title: t('planner.properties.round') },
|
|
{ value: 'square', title: t('planner.properties.square') },
|
|
],
|
|
},
|
|
{
|
|
key: 'lineJoin',
|
|
title: t('planner.properties.lineJoin'),
|
|
type: 'select',
|
|
groupable: true,
|
|
options: [
|
|
{ value: undefined, title: '' },
|
|
{ value: 'miter', title: t('planner.properties.miter') },
|
|
{ value: 'bevel', title: t('planner.properties.bevel') },
|
|
{ value: 'round', title: t('planner.properties.round') },
|
|
],
|
|
},
|
|
{
|
|
key: 'closed',
|
|
title: t('planner.properties.closed'),
|
|
type: 'boolean',
|
|
groupable: true,
|
|
},
|
|
];
|
|
|
|
const objectTypeProperties: ObjectProperties[] = [
|
|
{
|
|
type: 'line',
|
|
properties: lineProps,
|
|
},
|
|
{
|
|
type: 'curve',
|
|
properties: lineProps,
|
|
},
|
|
{
|
|
type: 'room',
|
|
properties: lineProps,
|
|
},
|
|
{
|
|
type: 'object',
|
|
properties: commonProps,
|
|
},
|
|
];
|
|
|
|
const currentLayer = computed(() =>
|
|
props.layers.find((layer) => layer.active && layer.visible),
|
|
);
|
|
|
|
// TODO multi edit
|
|
const selectedObject = computed(
|
|
() => currentLayer.value?.contents?.filter((obj) => obj.selected)[0],
|
|
);
|
|
|
|
const applicableProperties = computed(
|
|
() =>
|
|
selectedObject.value &&
|
|
objectTypeProperties.find(
|
|
(prop) => prop.type === selectedObject.value?.type,
|
|
),
|
|
);
|
|
|
|
const updateProp = (prop: ObjectProperty, value: unknown) => {
|
|
if (!currentLayer.value || !selectedObject.value) return;
|
|
if (prop.type === 'number') value = parseFloat(value as string);
|
|
emit(
|
|
'update',
|
|
currentLayer.value!.id,
|
|
selectedObject.value!.id,
|
|
prop.key,
|
|
value,
|
|
);
|
|
};
|
|
</script>
|