mirror of
https://github.com/gpxstudio/gpx.studio.git
synced 2025-09-03 17:12:31 +00:00
add new track/segment to edit menu, and to docs
This commit is contained in:
@@ -151,27 +151,18 @@
|
|||||||
<Shortcut key="O" ctrl={true} />
|
<Shortcut key="O" ctrl={true} />
|
||||||
</Menubar.Item>
|
</Menubar.Item>
|
||||||
<Menubar.Separator />
|
<Menubar.Separator />
|
||||||
<Menubar.Item
|
<Menubar.Item on:click={dbUtils.duplicateSelection} disabled={$selection.size == 0}>
|
||||||
on:click={dbUtils.duplicateSelection}
|
|
||||||
disabled={$selection.size == 0}
|
|
||||||
>
|
|
||||||
<Copy size="16" class="mr-1" />
|
<Copy size="16" class="mr-1" />
|
||||||
{$_('menu.duplicate')}
|
{$_('menu.duplicate')}
|
||||||
<Shortcut key="D" ctrl={true} />
|
<Shortcut key="D" ctrl={true} />
|
||||||
</Menubar.Item>
|
</Menubar.Item>
|
||||||
<Menubar.Separator />
|
<Menubar.Separator />
|
||||||
<Menubar.Item
|
<Menubar.Item on:click={dbUtils.deleteSelectedFiles} disabled={$selection.size == 0}>
|
||||||
on:click={dbUtils.deleteSelectedFiles}
|
|
||||||
disabled={$selection.size == 0}
|
|
||||||
>
|
|
||||||
<FileX size="16" class="mr-1" />
|
<FileX size="16" class="mr-1" />
|
||||||
{$_('menu.close')}
|
{$_('menu.close')}
|
||||||
<Shortcut key="⌫" ctrl={true} />
|
<Shortcut key="⌫" ctrl={true} />
|
||||||
</Menubar.Item>
|
</Menubar.Item>
|
||||||
<Menubar.Item
|
<Menubar.Item on:click={dbUtils.deleteAllFiles} disabled={$fileObservers.size == 0}>
|
||||||
on:click={dbUtils.deleteAllFiles}
|
|
||||||
disabled={$fileObservers.size == 0}
|
|
||||||
>
|
|
||||||
<FileX size="16" class="mr-1" />
|
<FileX size="16" class="mr-1" />
|
||||||
{$_('menu.close_all')}
|
{$_('menu.close_all')}
|
||||||
<Shortcut key="⌫" ctrl={true} shift={true} />
|
<Shortcut key="⌫" ctrl={true} shift={true} />
|
||||||
@@ -216,11 +207,7 @@
|
|||||||
disabled={$selection.size !== 1 ||
|
disabled={$selection.size !== 1 ||
|
||||||
!$selection
|
!$selection
|
||||||
.getSelected()
|
.getSelected()
|
||||||
.every(
|
.every((item) => item instanceof ListFileItem || item instanceof ListTrackItem)}
|
||||||
(item) =>
|
|
||||||
item instanceof ListFileItem ||
|
|
||||||
item instanceof ListTrackItem
|
|
||||||
)}
|
|
||||||
on:click={() => ($editMetadata = true)}
|
on:click={() => ($editMetadata = true)}
|
||||||
>
|
>
|
||||||
<Info size="16" class="mr-1" />
|
<Info size="16" class="mr-1" />
|
||||||
@@ -231,11 +218,7 @@
|
|||||||
disabled={$selection.size === 0 ||
|
disabled={$selection.size === 0 ||
|
||||||
!$selection
|
!$selection
|
||||||
.getSelected()
|
.getSelected()
|
||||||
.every(
|
.every((item) => item instanceof ListFileItem || item instanceof ListTrackItem)}
|
||||||
(item) =>
|
|
||||||
item instanceof ListFileItem ||
|
|
||||||
item instanceof ListTrackItem
|
|
||||||
)}
|
|
||||||
on:click={() => ($editStyle = true)}
|
on:click={() => ($editStyle = true)}
|
||||||
>
|
>
|
||||||
<PaintBucket size="16" class="mr-1" />
|
<PaintBucket size="16" class="mr-1" />
|
||||||
@@ -260,6 +243,29 @@
|
|||||||
{/if}
|
{/if}
|
||||||
<Shortcut key="H" ctrl={true} />
|
<Shortcut key="H" ctrl={true} />
|
||||||
</Menubar.Item>
|
</Menubar.Item>
|
||||||
|
{#if $verticalFileView}
|
||||||
|
{#if $selection.getSelected().some((item) => item instanceof ListFileItem)}
|
||||||
|
<Menubar.Separator />
|
||||||
|
<Menubar.Item
|
||||||
|
on:click={() => dbUtils.addNewTrack($selection.getSelected()[0].getFileId())}
|
||||||
|
disabled={$selection.size !== 1}
|
||||||
|
>
|
||||||
|
<Plus size="16" class="mr-1" />
|
||||||
|
{$_('menu.new_track')}
|
||||||
|
</Menubar.Item>
|
||||||
|
{:else if $selection.getSelected().some((item) => item instanceof ListTrackItem)}
|
||||||
|
<Menubar.Separator />
|
||||||
|
<Menubar.Item
|
||||||
|
on:click={() => {
|
||||||
|
let item = $selection.getSelected()[0];
|
||||||
|
dbUtils.addNewSegment(item.getFileId(), item.getTrackIndex());
|
||||||
|
}}
|
||||||
|
disabled={$selection.size !== 1}
|
||||||
|
>
|
||||||
|
<Plus size="16" class="mr-1" />
|
||||||
|
{$_('menu.new_segment')}
|
||||||
|
</Menubar.Item>
|
||||||
|
{/if}
|
||||||
<Menubar.Separator />
|
<Menubar.Separator />
|
||||||
<Menubar.Item on:click={selectAll} disabled={$fileObservers.size == 0}>
|
<Menubar.Item on:click={selectAll} disabled={$fileObservers.size == 0}>
|
||||||
<FileStack size="16" class="mr-1" />
|
<FileStack size="16" class="mr-1" />
|
||||||
@@ -277,7 +283,6 @@
|
|||||||
{$_('menu.center')}
|
{$_('menu.center')}
|
||||||
<Shortcut key="⏎" ctrl={true} />
|
<Shortcut key="⏎" ctrl={true} />
|
||||||
</Menubar.Item>
|
</Menubar.Item>
|
||||||
{#if $verticalFileView}
|
|
||||||
<Menubar.Separator />
|
<Menubar.Separator />
|
||||||
<Menubar.Item on:click={copySelection} disabled={$selection.size === 0}>
|
<Menubar.Item on:click={copySelection} disabled={$selection.size === 0}>
|
||||||
<ClipboardCopy size="16" class="mr-1" />
|
<ClipboardCopy size="16" class="mr-1" />
|
||||||
@@ -293,9 +298,7 @@
|
|||||||
disabled={$copied === undefined ||
|
disabled={$copied === undefined ||
|
||||||
$copied.length === 0 ||
|
$copied.length === 0 ||
|
||||||
($selection.size > 0 &&
|
($selection.size > 0 &&
|
||||||
!allowedPastes[$copied[0].level].includes(
|
!allowedPastes[$copied[0].level].includes($selection.getSelected().pop()?.level))}
|
||||||
$selection.getSelected().pop()?.level
|
|
||||||
))}
|
|
||||||
on:click={pasteSelection}
|
on:click={pasteSelection}
|
||||||
>
|
>
|
||||||
<ClipboardPaste size="16" class="mr-1" />
|
<ClipboardPaste size="16" class="mr-1" />
|
||||||
@@ -304,10 +307,7 @@
|
|||||||
</Menubar.Item>
|
</Menubar.Item>
|
||||||
{/if}
|
{/if}
|
||||||
<Menubar.Separator />
|
<Menubar.Separator />
|
||||||
<Menubar.Item
|
<Menubar.Item on:click={dbUtils.deleteSelection} disabled={$selection.size == 0}>
|
||||||
on:click={dbUtils.deleteSelection}
|
|
||||||
disabled={$selection.size == 0}
|
|
||||||
>
|
|
||||||
<Trash2 size="16" class="mr-1" />
|
<Trash2 size="16" class="mr-1" />
|
||||||
{$_('menu.delete')}
|
{$_('menu.delete')}
|
||||||
<Shortcut key="⌫" ctrl={true} />
|
<Shortcut key="⌫" ctrl={true} />
|
||||||
@@ -332,25 +332,17 @@
|
|||||||
</Menubar.CheckboxItem>
|
</Menubar.CheckboxItem>
|
||||||
<Menubar.Separator />
|
<Menubar.Separator />
|
||||||
<Menubar.Item inset on:click={switchBasemaps}>
|
<Menubar.Item inset on:click={switchBasemaps}>
|
||||||
<Map size="16" class="mr-1" />{$_('menu.switch_basemap')}<Shortcut
|
<Map size="16" class="mr-1" />{$_('menu.switch_basemap')}<Shortcut key="F1" />
|
||||||
key="F1"
|
|
||||||
/>
|
|
||||||
</Menubar.Item>
|
</Menubar.Item>
|
||||||
<Menubar.Item inset on:click={toggleOverlays}>
|
<Menubar.Item inset on:click={toggleOverlays}>
|
||||||
<Layers2 size="16" class="mr-1" />{$_('menu.toggle_overlays')}<Shortcut
|
<Layers2 size="16" class="mr-1" />{$_('menu.toggle_overlays')}<Shortcut key="F2" />
|
||||||
key="F2"
|
|
||||||
/>
|
|
||||||
</Menubar.Item>
|
</Menubar.Item>
|
||||||
<Menubar.Separator />
|
<Menubar.Separator />
|
||||||
<Menubar.CheckboxItem bind:checked={$distanceMarkers}>
|
<Menubar.CheckboxItem bind:checked={$distanceMarkers}>
|
||||||
<Coins size="16" class="mr-1" />{$_('menu.distance_markers')}<Shortcut
|
<Coins size="16" class="mr-1" />{$_('menu.distance_markers')}<Shortcut key="F3" />
|
||||||
key="F3"
|
|
||||||
/>
|
|
||||||
</Menubar.CheckboxItem>
|
</Menubar.CheckboxItem>
|
||||||
<Menubar.CheckboxItem bind:checked={$directionMarkers}>
|
<Menubar.CheckboxItem bind:checked={$directionMarkers}>
|
||||||
<Milestone size="16" class="mr-1" />{$_('menu.direction_markers')}<Shortcut
|
<Milestone size="16" class="mr-1" />{$_('menu.direction_markers')}<Shortcut key="F4" />
|
||||||
key="F4"
|
|
||||||
/>
|
|
||||||
</Menubar.CheckboxItem>
|
</Menubar.CheckboxItem>
|
||||||
<Menubar.Separator />
|
<Menubar.Separator />
|
||||||
<Menubar.Item inset on:click={toggle3D}>
|
<Menubar.Item inset on:click={toggle3D}>
|
||||||
@@ -367,39 +359,27 @@
|
|||||||
{$_('menu.settings')}
|
{$_('menu.settings')}
|
||||||
</span>
|
</span>
|
||||||
</Menubar.Trigger>
|
</Menubar.Trigger>
|
||||||
<Menubar.Content class="border-none"
|
<Menubar.Content class="border-none">
|
||||||
><Menubar.Sub>
|
<Menubar.Sub>
|
||||||
<Menubar.SubTrigger>
|
<Menubar.SubTrigger>
|
||||||
<Ruler size="16" class="mr-1" />{$_('menu.distance_units')}
|
<Ruler size="16" class="mr-1" />{$_('menu.distance_units')}
|
||||||
</Menubar.SubTrigger>
|
</Menubar.SubTrigger>
|
||||||
<Menubar.SubContent>
|
<Menubar.SubContent>
|
||||||
<Menubar.RadioGroup bind:value={$distanceUnits}>
|
<Menubar.RadioGroup bind:value={$distanceUnits}>
|
||||||
<Menubar.RadioItem value="metric"
|
<Menubar.RadioItem value="metric">{$_('menu.metric')}</Menubar.RadioItem>
|
||||||
>{$_('menu.metric')}</Menubar.RadioItem
|
<Menubar.RadioItem value="imperial">{$_('menu.imperial')}</Menubar.RadioItem>
|
||||||
>
|
<Menubar.RadioItem value="nautical">{$_('menu.nautical')}</Menubar.RadioItem>
|
||||||
<Menubar.RadioItem value="imperial"
|
|
||||||
>{$_('menu.imperial')}</Menubar.RadioItem
|
|
||||||
>
|
|
||||||
<Menubar.RadioItem value="nautical"
|
|
||||||
>{$_('menu.nautical')}</Menubar.RadioItem
|
|
||||||
>
|
|
||||||
</Menubar.RadioGroup>
|
</Menubar.RadioGroup>
|
||||||
</Menubar.SubContent>
|
</Menubar.SubContent>
|
||||||
</Menubar.Sub>
|
</Menubar.Sub>
|
||||||
<Menubar.Sub>
|
<Menubar.Sub>
|
||||||
<Menubar.SubTrigger
|
<Menubar.SubTrigger>
|
||||||
><Zap size="16" class="mr-1" />{$_(
|
<Zap size="16" class="mr-1" />{$_('menu.velocity_units')}
|
||||||
'menu.velocity_units'
|
</Menubar.SubTrigger>
|
||||||
)}</Menubar.SubTrigger
|
|
||||||
>
|
|
||||||
<Menubar.SubContent>
|
<Menubar.SubContent>
|
||||||
<Menubar.RadioGroup bind:value={$velocityUnits}>
|
<Menubar.RadioGroup bind:value={$velocityUnits}>
|
||||||
<Menubar.RadioItem value="speed"
|
<Menubar.RadioItem value="speed">{$_('quantities.speed')}</Menubar.RadioItem>
|
||||||
>{$_('quantities.speed')}</Menubar.RadioItem
|
<Menubar.RadioItem value="pace">{$_('quantities.pace')}</Menubar.RadioItem>
|
||||||
>
|
|
||||||
<Menubar.RadioItem value="pace"
|
|
||||||
>{$_('quantities.pace')}</Menubar.RadioItem
|
|
||||||
>
|
|
||||||
</Menubar.RadioGroup>
|
</Menubar.RadioGroup>
|
||||||
</Menubar.SubContent>
|
</Menubar.SubContent>
|
||||||
</Menubar.Sub>
|
</Menubar.Sub>
|
||||||
@@ -409,12 +389,8 @@
|
|||||||
</Menubar.SubTrigger>
|
</Menubar.SubTrigger>
|
||||||
<Menubar.SubContent>
|
<Menubar.SubContent>
|
||||||
<Menubar.RadioGroup bind:value={$temperatureUnits}>
|
<Menubar.RadioGroup bind:value={$temperatureUnits}>
|
||||||
<Menubar.RadioItem value="celsius"
|
<Menubar.RadioItem value="celsius">{$_('menu.celsius')}</Menubar.RadioItem>
|
||||||
>{$_('menu.celsius')}</Menubar.RadioItem
|
<Menubar.RadioItem value="fahrenheit">{$_('menu.fahrenheit')}</Menubar.RadioItem>
|
||||||
>
|
|
||||||
<Menubar.RadioItem value="fahrenheit"
|
|
||||||
>{$_('menu.fahrenheit')}</Menubar.RadioItem
|
|
||||||
>
|
|
||||||
</Menubar.RadioGroup>
|
</Menubar.RadioGroup>
|
||||||
</Menubar.SubContent>
|
</Menubar.SubContent>
|
||||||
</Menubar.Sub>
|
</Menubar.Sub>
|
||||||
@@ -450,11 +426,8 @@
|
|||||||
setMode(value);
|
setMode(value);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Menubar.RadioItem value="light"
|
<Menubar.RadioItem value="light">{$_('menu.light')}</Menubar.RadioItem>
|
||||||
>{$_('menu.light')}</Menubar.RadioItem
|
<Menubar.RadioItem value="dark">{$_('menu.dark')}</Menubar.RadioItem>
|
||||||
>
|
|
||||||
<Menubar.RadioItem value="dark">{$_('menu.dark')}</Menubar.RadioItem
|
|
||||||
>
|
|
||||||
</Menubar.RadioGroup>
|
</Menubar.RadioGroup>
|
||||||
</Menubar.SubContent>
|
</Menubar.SubContent>
|
||||||
</Menubar.Sub>
|
</Menubar.Sub>
|
||||||
@@ -466,12 +439,8 @@
|
|||||||
</Menubar.SubTrigger>
|
</Menubar.SubTrigger>
|
||||||
<Menubar.SubContent>
|
<Menubar.SubContent>
|
||||||
<Menubar.RadioGroup bind:value={$streetViewSource}>
|
<Menubar.RadioGroup bind:value={$streetViewSource}>
|
||||||
<Menubar.RadioItem value="mapillary"
|
<Menubar.RadioItem value="mapillary">{$_('menu.mapillary')}</Menubar.RadioItem>
|
||||||
>{$_('menu.mapillary')}</Menubar.RadioItem
|
<Menubar.RadioItem value="google">{$_('menu.google')}</Menubar.RadioItem>
|
||||||
>
|
|
||||||
<Menubar.RadioItem value="google"
|
|
||||||
>{$_('menu.google')}</Menubar.RadioItem
|
|
||||||
>
|
|
||||||
</Menubar.RadioGroup>
|
</Menubar.RadioGroup>
|
||||||
</Menubar.SubContent>
|
</Menubar.SubContent>
|
||||||
</Menubar.Sub>
|
</Menubar.Sub>
|
||||||
|
@@ -248,10 +248,7 @@
|
|||||||
{#if item instanceof ListFileItem}
|
{#if item instanceof ListFileItem}
|
||||||
<ContextMenu.Item
|
<ContextMenu.Item
|
||||||
disabled={!singleSelection}
|
disabled={!singleSelection}
|
||||||
on:click={() =>
|
on:click={() => dbUtils.addNewTrack(item.getFileId())}
|
||||||
dbUtils.applyToFile(item.getFileId(), (file) =>
|
|
||||||
file.replaceTracks(file.trk.length, file.trk.length, [new Track()])
|
|
||||||
)}
|
|
||||||
>
|
>
|
||||||
<Plus size="16" class="mr-1" />
|
<Plus size="16" class="mr-1" />
|
||||||
{$_('menu.new_track')}
|
{$_('menu.new_track')}
|
||||||
@@ -260,17 +257,7 @@
|
|||||||
{:else if item instanceof ListTrackItem}
|
{:else if item instanceof ListTrackItem}
|
||||||
<ContextMenu.Item
|
<ContextMenu.Item
|
||||||
disabled={!singleSelection}
|
disabled={!singleSelection}
|
||||||
on:click={() => {
|
on:click={() => dbUtils.addNewSegment(item.getFileId(), item.getTrackIndex())}
|
||||||
let trackIndex = item.getTrackIndex();
|
|
||||||
dbUtils.applyToFile(item.getFileId(), (file) =>
|
|
||||||
file.replaceTrackSegments(
|
|
||||||
trackIndex,
|
|
||||||
file.trk[trackIndex].trkseg.length,
|
|
||||||
file.trk[trackIndex].trkseg.length,
|
|
||||||
[new TrackSegment()]
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<Plus size="16" class="mr-1" />
|
<Plus size="16" class="mr-1" />
|
||||||
{$_('menu.new_segment')}
|
{$_('menu.new_segment')}
|
||||||
|
@@ -512,6 +512,15 @@ export const dbUtils = {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
addNewTrack: (fileId: string) => {
|
||||||
|
dbUtils.applyToFile(fileId, (file) => file.replaceTracks(file.trk.length, file.trk.length, [new Track()]));
|
||||||
|
},
|
||||||
|
addNewSegment: (fileId: string, trackIndex: number) => {
|
||||||
|
dbUtils.applyToFile(fileId, (file) => {
|
||||||
|
let track = file.trk[trackIndex];
|
||||||
|
track.replaceTrackSegments(track.trkseg.length, track.trkseg.length, [new TrackSegment()]);
|
||||||
|
});
|
||||||
|
},
|
||||||
reverseSelection: () => {
|
reverseSelection: () => {
|
||||||
if (!get(selection).hasAnyChildren(new ListRootItem(), true, ['waypoints']) || get(gpxStatistics).local.points?.length <= 1) {
|
if (!get(selection).hasAnyChildren(new ListRootItem(), true, ['waypoints']) || get(gpxStatistics).local.points?.length <= 1) {
|
||||||
return;
|
return;
|
||||||
|
@@ -3,7 +3,7 @@ title: Edit actions
|
|||||||
---
|
---
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Undo2, Redo2, Info, PaintBucket, EyeOff, FileStack, ClipboardCopy, Scissors, ClipboardPaste, Trash2, Maximize } from 'lucide-svelte';
|
import { Undo2, Redo2, Info, PaintBucket, EyeOff, FileStack, ClipboardCopy, Scissors, ClipboardPaste, Trash2, Maximize, Plus } from 'lucide-svelte';
|
||||||
import DocsNote from '$lib/components/docs/DocsNote.svelte';
|
import DocsNote from '$lib/components/docs/DocsNote.svelte';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -31,6 +31,28 @@ Open the appearance dialog, where you can change the color, opacity, and width o
|
|||||||
|
|
||||||
Toggle the visibility of the selected file items on the map.
|
Toggle the visibility of the selected file items on the map.
|
||||||
|
|
||||||
|
### <Plus size="16" class="inline-block" style="margin-bottom: 2px" /> New track
|
||||||
|
|
||||||
|
Create a new track in the selected file.
|
||||||
|
|
||||||
|
<DocsNote>
|
||||||
|
|
||||||
|
This action is only available when the vertical layout of the files list is enabled.
|
||||||
|
Additionally, the selection must be a single file.
|
||||||
|
|
||||||
|
</DocsNote>
|
||||||
|
|
||||||
|
### <Plus size="16" class="inline-block" style="margin-bottom: 2px" /> New segment
|
||||||
|
|
||||||
|
Create a new segment in the selected track.
|
||||||
|
|
||||||
|
<DocsNote>
|
||||||
|
|
||||||
|
This action is only available when the vertical layout of the files list is enabled.
|
||||||
|
Additionally, the selection must be a single track.
|
||||||
|
|
||||||
|
</DocsNote>
|
||||||
|
|
||||||
### <FileStack size="16" class="inline-block" style="margin-bottom: 2px" /> Select all
|
### <FileStack size="16" class="inline-block" style="margin-bottom: 2px" /> Select all
|
||||||
|
|
||||||
Add all file items in the current hierarchy level to the selection.
|
Add all file items in the current hierarchy level to the selection.
|
||||||
|
Reference in New Issue
Block a user