Files
gpx.studio/website/src/lib/components/file-list/StyleDialog.svelte

168 lines
4.3 KiB
Svelte
Raw Normal View History

2024-06-27 17:14:35 +02:00
<script lang="ts">
import { Button } from '$lib/components/ui/button';
import { Input } from '$lib/components/ui/input';
import { Label } from '$lib/components/ui/label/index.js';
import { Slider } from '$lib/components/ui/slider';
import * as Popover from '$lib/components/ui/popover';
import { dbUtils, getFile, settings } from '$lib/db';
import { Save } from 'lucide-svelte';
import { ListFileItem, ListTrackItem, type ListItem } from './FileList';
import { selection } from './Selection';
2024-06-27 18:23:11 +02:00
import { editStyle, gpxLayers } from '$lib/stores';
2024-06-27 17:14:35 +02:00
import { _ } from 'svelte-i18n';
export let item: ListItem;
export let open = false;
const { defaultOpacity, defaultWidth } = settings;
2024-06-27 17:14:35 +02:00
let colors: string[] = [];
let color: string | undefined = undefined;
let opacity: number[] = [];
let width: number[] = [];
2024-06-27 17:14:35 +02:00
let colorChanged = false;
let opacityChanged = false;
let widthChanged = false;
2024-06-27 17:14:35 +02:00
function setStyleInputs() {
colors = [];
opacity = [];
width = [];
2024-06-27 17:14:35 +02:00
$selection.forEach((item) => {
if (item instanceof ListFileItem) {
let file = getFile(item.getFileId());
let layer = gpxLayers.get(item.getFileId());
if (file && layer) {
let style = file.getStyle();
style.color.push(layer.layerColor);
style.color.forEach((c) => {
if (!colors.includes(c)) {
colors.push(c);
}
});
style.opacity.forEach((o) => {
if (!opacity.includes(o)) {
opacity.push(o);
}
});
style.width.forEach((w) => {
if (!width.includes(w)) {
width.push(w);
2024-06-27 17:14:35 +02:00
}
});
}
} else if (item instanceof ListTrackItem) {
let file = getFile(item.getFileId());
let layer = gpxLayers.get(item.getFileId());
if (file && layer) {
let track = file.trk[item.getTrackIndex()];
let style = track.getStyle();
if (style) {
2024-12-28 15:16:32 +01:00
if (style['gpx_style:color'] && !colors.includes(style['gpx_style:color'])) {
colors.push(style['gpx_style:color']);
2024-06-27 17:14:35 +02:00
}
2024-12-28 15:16:32 +01:00
if (style['gpx_style:opacity'] && !opacity.includes(style['gpx_style:opacity'])) {
opacity.push(style['gpx_style:opacity']);
2024-06-27 17:14:35 +02:00
}
if (style['gpx_style:width'] && !width.includes(style['gpx_style:width'])) {
width.push(style['gpx_style:width']);
2024-06-27 17:14:35 +02:00
}
}
if (!colors.includes(layer.layerColor)) {
colors.push(layer.layerColor);
}
}
}
});
color = colors[0];
opacity = [opacity[0] ?? $defaultOpacity];
width = [width[0] ?? $defaultWidth];
2024-06-27 17:14:35 +02:00
colorChanged = false;
opacityChanged = false;
widthChanged = false;
2024-06-27 17:14:35 +02:00
}
$: if ($selection && open) {
setStyleInputs();
}
2024-06-27 18:23:11 +02:00
$: if (!open) {
$editStyle = false;
}
2024-06-27 17:14:35 +02:00
</script>
<Popover.Root bind:open>
<Popover.Trigger />
<Popover.Content side="top" sideOffset={22} alignOffset={30} class="flex flex-col gap-3">
<Label class="flex flex-row gap-2 items-center justify-between">
{$_('menu.style.color')}
<Input
bind:value={color}
type="color"
class="p-0 h-6 w-40"
on:change={() => (colorChanged = true)}
/>
</Label>
<Label class="flex flex-row gap-2 items-center justify-between">
{$_('menu.style.opacity')}
<div class="w-40 p-2">
<Slider
bind:value={opacity}
min={0.3}
max={1}
step={0.1}
onValueChange={() => (opacityChanged = true)}
/>
</div>
</Label>
<Label class="flex flex-row gap-2 items-center justify-between">
2024-07-09 17:49:18 +02:00
{$_('menu.style.width')}
2024-06-27 17:14:35 +02:00
<div class="w-40 p-2">
<Slider
bind:value={width}
id="width"
2024-06-27 17:14:35 +02:00
min={1}
max={10}
step={1}
onValueChange={() => (widthChanged = true)}
2024-06-27 17:14:35 +02:00
/>
</div>
</Label>
<Button
variant="outline"
disabled={!colorChanged && !opacityChanged && !widthChanged}
2024-06-27 17:14:35 +02:00
on:click={() => {
let style = {};
if (colorChanged) {
2024-12-28 15:16:32 +01:00
style['gpx_style:color'] = color;
2024-06-27 17:14:35 +02:00
}
if (opacityChanged) {
2024-12-28 15:16:32 +01:00
style['gpx_style:opacity'] = opacity[0];
2024-06-27 17:14:35 +02:00
}
if (widthChanged) {
style['gpx_style:width'] = width[0];
2024-06-27 17:14:35 +02:00
}
dbUtils.setStyleToSelection(style);
if (item instanceof ListFileItem && $selection.size === gpxLayers.size) {
2024-12-28 15:16:32 +01:00
if (style['gpx_style:opacity']) {
$defaultOpacity = style['gpx_style:opacity'];
2024-06-27 17:14:35 +02:00
}
if (style['gpx_style:width']) {
$defaultWidth = style['gpx_style:width'];
2024-06-27 17:14:35 +02:00
}
}
open = false;
}}
>
<Save size="16" class="mr-1" />
{$_('menu.metadata.save')}
</Button>
</Popover.Content>
</Popover.Root>