From 2a4dfe010ef50a49a5818336283072750f291bd0 Mon Sep 17 00:00:00 2001 From: vcoppe Date: Fri, 30 Jan 2026 21:17:59 +0100 Subject: [PATCH] improve color management --- .../file-list/FileListNodeLabel.svelte | 25 +++++----------- .../lib/components/map/gpx-layer/gpx-layer.ts | 30 +++++++++++++++---- .../components/map/gpx-layer/gpx-layers.ts | 2 ++ 3 files changed, 35 insertions(+), 22 deletions(-) diff --git a/website/src/lib/components/file-list/FileListNodeLabel.svelte b/website/src/lib/components/file-list/FileListNodeLabel.svelte index 78d970fe3..16b0c6724 100644 --- a/website/src/lib/components/file-list/FileListNodeLabel.svelte +++ b/website/src/lib/components/file-list/FileListNodeLabel.svelte @@ -34,11 +34,10 @@ import { editStyle } from '$lib/components/file-list/style/utils.svelte'; import { getSymbolKey, symbols } from '$lib/assets/symbols'; import { selection, copied, cut } from '$lib/logic/selection'; - import { map } from '$lib/components/map/map'; import { fileActions, pasteSelection } from '$lib/logic/file-actions'; import { allHidden } from '$lib/logic/hidden'; import { boundsManager } from '$lib/logic/bounds'; - import { gpxLayers } from '$lib/components/map/gpx-layer/gpx-layers'; + import { gpxColors, gpxLayers } from '$lib/components/map/gpx-layer/gpx-layers'; import { fileStateCollection } from '$lib/logic/file-state'; import { waypointPopup } from '$lib/components/map/gpx-layer/gpx-layer-popup'; import { allowedPastes } from './sortable-file-list'; @@ -58,19 +57,11 @@ let singleSelection = $derived($selection.size === 1); - let nodeColors: string[] = $state([]); - - $effect.pre(() => { + let nodeColors: string[] = $derived.by(() => { let colors: string[] = []; - if (node && $map) { + if (node) { if (node instanceof GPXFile) { - let defaultColor = undefined; - - let layer = gpxLayers.getLayer(item.getFileId()); - if (layer) { - defaultColor = layer.layerColor; - } - + let defaultColor = $gpxColors.get(item.getFileId()); let style = node.getStyle(defaultColor); colors = style.color; } else if (node instanceof Track) { @@ -83,14 +74,14 @@ colors.push(style['gpx_style:color']); } if (colors.length === 0) { - let layer = gpxLayers.getLayer(item.getFileId()); - if (layer) { - colors.push(layer.layerColor); + let defaultColor = $gpxColors.get(item.getFileId()); + if (defaultColor) { + colors.push(defaultColor); } } } } - nodeColors = colors; + return colors; }); let symbolKey = $derived(node instanceof Waypoint ? getSymbolKey(node.sym) : undefined); diff --git a/website/src/lib/components/map/gpx-layer/gpx-layer.ts b/website/src/lib/components/map/gpx-layer/gpx-layer.ts index 4439fd9a0..ee81ca9ba 100644 --- a/website/src/lib/components/map/gpx-layer/gpx-layer.ts +++ b/website/src/lib/components/map/gpx-layer/gpx-layer.ts @@ -22,6 +22,7 @@ import { fileActionManager } from '$lib/logic/file-action-manager'; import { fileActions } from '$lib/logic/file-actions'; import { splitAs } from '$lib/components/toolbar/tools/scissors/scissors'; import { mapCursor, MapCursorState } from '$lib/logic/map-cursor'; +import { gpxColors } from '$lib/components/map/gpx-layer/gpx-layers'; const colors = [ '#ff0000', @@ -43,16 +44,35 @@ for (let color of colors) { } // Get the color with the least amount of uses -function getColor() { +function getColor(fileId: string) { let color = colors.reduce((a, b) => (colorCount[a] <= colorCount[b] ? a : b)); colorCount[color]++; + gpxColors.update((colors) => { + colors.set(fileId, color); + return colors; + }); return color; } -function decrementColor(color: string) { +function replaceColor(fileId: string, oldColor: string, newColor: string) { + if (colorCount.hasOwnProperty(oldColor)) { + colorCount[oldColor]--; + } + colorCount[newColor]++; + gpxColors.update((colors) => { + colors.set(fileId, newColor); + return colors; + }); +} + +function removeColor(fileId: string, color: string) { if (colorCount.hasOwnProperty(color)) { colorCount[color]--; } + gpxColors.update((colors) => { + colors.delete(fileId); + return colors; + }); } export function getSvgForSymbol(symbol?: string | undefined, layerColor?: string | undefined) { @@ -121,7 +141,7 @@ export class GPXLayer { constructor(fileId: string, file: Readable) { this.fileId = fileId; this.file = file; - this.layerColor = getColor(); + this.layerColor = getColor(fileId); this.unsubscribe.push( map.subscribe(($map) => { if ($map) { @@ -158,7 +178,7 @@ export class GPXLayer { file._data.style.color && this.layerColor !== `#${file._data.style.color}` ) { - decrementColor(this.layerColor); + replaceColor(this.fileId, this.layerColor, `#${file._data.style.color}`); this.layerColor = `#${file._data.style.color}`; } @@ -364,7 +384,7 @@ export class GPXLayer { this.unsubscribe.forEach((unsubscribe) => unsubscribe()); - decrementColor(this.layerColor); + removeColor(this.fileId, this.layerColor); } moveToFront() { diff --git a/website/src/lib/components/map/gpx-layer/gpx-layers.ts b/website/src/lib/components/map/gpx-layer/gpx-layers.ts index 1dd05a021..aa3c45e87 100644 --- a/website/src/lib/components/map/gpx-layer/gpx-layers.ts +++ b/website/src/lib/components/map/gpx-layer/gpx-layers.ts @@ -1,4 +1,5 @@ import { GPXFileStateCollectionObserver } from '$lib/logic/file-state'; +import { writable } from 'svelte/store'; import { GPXLayer } from './gpx-layer'; export class GPXLayerCollection { @@ -42,3 +43,4 @@ export class GPXLayerCollection { } export const gpxLayers = new GPXLayerCollection(); +export const gpxColors = writable(new Map());