mirror of
https://github.com/gpxstudio/gpx.studio.git
synced 2026-10-07 06:14:07 +00:00
progress
This commit is contained in:
@@ -32,6 +32,7 @@
|
||||
import { isHidden } from '$lib/file-visibility';
|
||||
import {
|
||||
elementId,
|
||||
isInClipboard,
|
||||
isSelected,
|
||||
selectedElementIds,
|
||||
selectionSize,
|
||||
@@ -105,7 +106,7 @@
|
||||
|
||||
let hidden = $derived(isHidden(fileState, elementId(node)));
|
||||
// cut elements are greyed until they are pasted
|
||||
let isCut = $derived($clipboard?.cut === true && isSelected($clipboard.selection, node));
|
||||
let isCut = $derived($clipboard?.cut === true && isInClipboard($clipboard, node));
|
||||
</script>
|
||||
|
||||
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
||||
|
||||
@@ -362,7 +362,11 @@ class Engine {
|
||||
* Pastes the clipboard, depending on the selection: the files, tracks and segments become new
|
||||
* files when nothing is selected, tracks and waypoints are added to a selected file,
|
||||
* segments to a selected track, and pasted after a selected track, segment or waypoint of the
|
||||
* same kind. The pasted elements are selected and the clipboard is emptied.
|
||||
* same kind. The pasted elements are selected.
|
||||
*
|
||||
* What is pasted is always the elements as they were when they were copied or cut, even if
|
||||
* they were changed or deleted since. It can be pasted several times: what was copied is
|
||||
* copied again, what was cut is moved the first time and copied after that.
|
||||
*/
|
||||
paste() {
|
||||
return this.run((w) => w.paste());
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import { describe, it } from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import type { FileStructure, Selection } from 'gpx-rs';
|
||||
import type { Clipboard, FileStructure, Selection } from 'gpx-rs';
|
||||
import type { VisibilityState } from './file-visibility';
|
||||
import {
|
||||
elementId,
|
||||
hasSelectionWithin,
|
||||
isCovered,
|
||||
isInClipboard,
|
||||
isEmpty,
|
||||
isSelected,
|
||||
isSelectionHidden,
|
||||
@@ -75,6 +76,26 @@ describe('selection helpers', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('tells which nodes are in the clipboard', () => {
|
||||
const clipboard = (type: Clipboard['type'], ids: string[]): Clipboard => ({
|
||||
type,
|
||||
ids,
|
||||
cut: true,
|
||||
});
|
||||
assert.deepEqual(
|
||||
matching(empty, (_, node) => isInClipboard(undefined, node)),
|
||||
[]
|
||||
);
|
||||
const inClipboard = (c: Clipboard) =>
|
||||
Object.keys(nodes).filter((name) => isInClipboard(c, nodes[name]));
|
||||
assert.deepEqual(inClipboard(clipboard('files', ['F2'])), ['F2']);
|
||||
assert.deepEqual(inClipboard(clipboard('tracks', ['T2', 'S1'])), ['T2']);
|
||||
assert.deepEqual(inClipboard(clipboard('segments', ['S1', 'S3'])), ['S1', 'S3']);
|
||||
assert.deepEqual(inClipboard(clipboard('waypoints', ['W2'])), ['W2']);
|
||||
// not mixed up with the other kinds of elements
|
||||
assert.deepEqual(inClipboard(clipboard('files', ['T1', 'S1', 'W1'])), []);
|
||||
});
|
||||
|
||||
it('counts the selected elements', () => {
|
||||
assert.equal(selectionSize(empty), 0);
|
||||
assert.equal(selectionSize(files('F1', 'F2')), 2);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { Selection } from 'gpx-rs';
|
||||
import type { Clipboard, Selection } from 'gpx-rs';
|
||||
import { isHidden, waypointsKey, type VisibilityState } from '$lib/file-visibility';
|
||||
|
||||
/**
|
||||
@@ -51,6 +51,25 @@ export function selectedFileIds(selection: Selection): string[] {
|
||||
}
|
||||
}
|
||||
|
||||
/** Whether the node is one of the elements in the clipboard. */
|
||||
export function isInClipboard(clipboard: Clipboard | undefined, node: FileTreeNode): boolean {
|
||||
if (!clipboard) {
|
||||
return false;
|
||||
}
|
||||
switch (node.type) {
|
||||
case 'file':
|
||||
return clipboard.type === 'files' && clipboard.ids.includes(node.fileId);
|
||||
case 'track':
|
||||
return clipboard.type === 'tracks' && clipboard.ids.includes(node.trackId);
|
||||
case 'segment':
|
||||
return clipboard.type === 'segments' && clipboard.ids.includes(node.segmentId);
|
||||
case 'waypoint':
|
||||
return clipboard.type === 'waypoints' && clipboard.ids.includes(node.waypointId);
|
||||
case 'waypoints':
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/** Number of selected elements (the waypoints node counts for one). */
|
||||
export function selectionSize(selection: Selection): number {
|
||||
switch (selection.type) {
|
||||
|
||||
Reference in New Issue
Block a user