mirror of
https://github.com/gpxstudio/gpx.studio.git
synced 2026-10-09 23:26:31 +00:00
reverse
This commit is contained in:
1 parent
df07892e76
commit
a48608840f
6 files changed
+493
-265
No files matched your search
@@ -156,7 +156,7 @@
|
||||
variant="outline"
|
||||
class="gap-1 text-xs px-1.5 py-1.5 h-fit"
|
||||
disabled={!validSelection}
|
||||
onclick={fileActions.reverseSelection}
|
||||
onclick={() => engine.reverse()}
|
||||
>
|
||||
<ArrowRightLeft class="size-3" />{i18n._('toolbar.routing.reverse.button')}
|
||||
</ButtonWithTooltip>
|
||||
|
||||
@@ -636,6 +636,15 @@ class Engine {
|
||||
return this.run((w) => w.new_track_segment());
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverses the direction of the selection: the whole of each selected file or track, or each
|
||||
* selected segment on its own. The timestamps are mirrored. Resolves to `false` when there is
|
||||
* nothing to reverse (fewer than two trackpoints).
|
||||
*/
|
||||
reverse() {
|
||||
return this.run((w) => w.reverse());
|
||||
}
|
||||
|
||||
metadata(name: string, desc: string) {
|
||||
return this.run((w) => w.metadata(name, desc));
|
||||
}
|
||||
|
||||
@@ -101,121 +101,6 @@ export async function loadFiles(list: FileList | File[]): Promise<string[]> {
|
||||
|
||||
// Helper functions for file operations
|
||||
export const fileActions = {
|
||||
add: (file: GPXFile) => {
|
||||
if (file._data.id === undefined) {
|
||||
file._data.id = getFileIds(1)[0];
|
||||
}
|
||||
return fileActionManager.applyGlobal((draft) => {
|
||||
draft.set(file._data.id, freeze(file));
|
||||
});
|
||||
},
|
||||
addMultiple: (files: GPXFile[]) => {
|
||||
let ids = getFileIds(files.length);
|
||||
fileActionManager.applyGlobal((draft) => {
|
||||
files.forEach((file, index) => {
|
||||
file._data.id = ids[index];
|
||||
draft.set(file._data.id, freeze(file));
|
||||
});
|
||||
});
|
||||
return ids;
|
||||
},
|
||||
duplicateSelection: () => {
|
||||
if (get(selection).size === 0) {
|
||||
return;
|
||||
}
|
||||
fileActionManager.applyGlobal((draft) => {
|
||||
let ids = getFileIds(get(settings.fileOrder).length);
|
||||
let index = 0;
|
||||
selection.applyToOrderedSelectedItemsFromFile((fileId, level, items) => {
|
||||
if (level === ListLevel.FILE) {
|
||||
let file = fileStateCollection.getFile(fileId);
|
||||
if (file) {
|
||||
let newFile = file.clone();
|
||||
newFile._data.id = ids[index++];
|
||||
draft.set(newFile._data.id, freeze(newFile));
|
||||
}
|
||||
} else {
|
||||
let file = draft.get(fileId);
|
||||
if (file) {
|
||||
if (level === ListLevel.TRACK) {
|
||||
for (let item of items) {
|
||||
let trackIndex = (item as ListTrackItem).getTrackIndex();
|
||||
file.replaceTracks(trackIndex + 1, trackIndex, [
|
||||
file.trk[trackIndex].clone(),
|
||||
]);
|
||||
}
|
||||
} else if (level === ListLevel.SEGMENT) {
|
||||
for (let item of items) {
|
||||
let trackIndex = (item as ListTrackSegmentItem).getTrackIndex();
|
||||
let segmentIndex = (item as ListTrackSegmentItem).getSegmentIndex();
|
||||
file.replaceTrackSegments(
|
||||
trackIndex,
|
||||
segmentIndex + 1,
|
||||
segmentIndex,
|
||||
[file.trk[trackIndex].trkseg[segmentIndex].clone()]
|
||||
);
|
||||
}
|
||||
} else if (level === ListLevel.WAYPOINTS) {
|
||||
file.replaceWaypoints(
|
||||
file.wpt.length,
|
||||
file.wpt.length - 1,
|
||||
file.wpt.map((wpt) => wpt.clone())
|
||||
);
|
||||
} else if (level === ListLevel.WAYPOINT) {
|
||||
for (let item of items) {
|
||||
let waypointIndex = (item as ListWaypointItem).getWaypointIndex();
|
||||
file.replaceWaypoints(waypointIndex + 1, waypointIndex, [
|
||||
file.wpt[waypointIndex].clone(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
addNewTrack: (fileId: string) => {
|
||||
fileActionManager.applyToFile(fileId, (file) =>
|
||||
file.replaceTracks(file.trk.length, file.trk.length, [new Track()])
|
||||
);
|
||||
},
|
||||
addNewSegment: (fileId: string, trackIndex: number) => {
|
||||
fileActionManager.applyToFile(fileId, (file) => {
|
||||
let track = file.trk[trackIndex];
|
||||
track.replaceTrackSegments(track.trkseg.length, track.trkseg.length, [
|
||||
new TrackSegment(),
|
||||
]);
|
||||
});
|
||||
},
|
||||
reverseSelection: () => {
|
||||
if (
|
||||
!get(selection).hasAnyChildren(new ListRootItem(), true, ['waypoints']) ||
|
||||
get(gpxStatistics).global.length <= 1
|
||||
) {
|
||||
return;
|
||||
}
|
||||
fileActionManager.applyGlobal((draft) => {
|
||||
selection.applyToOrderedSelectedItemsFromFile((fileId, level, items) => {
|
||||
let file = draft.get(fileId);
|
||||
if (file) {
|
||||
if (level === ListLevel.FILE) {
|
||||
file.reverse();
|
||||
} else if (level === ListLevel.TRACK) {
|
||||
for (let item of items) {
|
||||
let trackIndex = (item as ListTrackItem).getTrackIndex();
|
||||
file.reverseTrack(trackIndex);
|
||||
}
|
||||
} else if (level === ListLevel.SEGMENT) {
|
||||
for (let item of items) {
|
||||
let trackIndex = (item as ListTrackSegmentItem).getTrackIndex();
|
||||
let segmentIndex = (item as ListTrackSegmentItem).getSegmentIndex();
|
||||
file.reverseTrackSegment(trackIndex, segmentIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
createRoundTripForSelection() {
|
||||
if (!get(selection).hasAnyChildren(new ListRootItem(), true, ['waypoints'])) {
|
||||
return;
|
||||
@@ -601,136 +486,6 @@ export const fileActions = {
|
||||
});
|
||||
});
|
||||
},
|
||||
addOrUpdateWaypoint: (waypoint: WaypointType, item?: ListWaypointItem) => {
|
||||
getElevation([waypoint.attributes]).then((elevation) => {
|
||||
if (item) {
|
||||
fileActionManager.applyToFile(item.getFileId(), (file) => {
|
||||
let wpt = file.wpt[item.getWaypointIndex()];
|
||||
wpt.name = waypoint.name;
|
||||
wpt.desc = waypoint.desc;
|
||||
wpt.cmt = waypoint.cmt;
|
||||
wpt.sym = waypoint.sym;
|
||||
wpt.link = waypoint.link;
|
||||
wpt.setCoordinates(waypoint.attributes);
|
||||
wpt.ele = elevation[0];
|
||||
});
|
||||
} else {
|
||||
let fileIds = new Set<string>();
|
||||
get(selection)
|
||||
.getSelected()
|
||||
.forEach((item) => {
|
||||
fileIds.add(item.getFileId());
|
||||
});
|
||||
let wpt = new Waypoint(waypoint);
|
||||
wpt.ele = elevation[0];
|
||||
fileActionManager.applyToFiles(Array.from(fileIds), (file) =>
|
||||
file.replaceWaypoints(file.wpt.length, file.wpt.length, [wpt])
|
||||
);
|
||||
}
|
||||
});
|
||||
},
|
||||
deleteWaypoint: (fileId: string, waypointIndex: number) => {
|
||||
fileActionManager.applyToFile(fileId, (file) =>
|
||||
file.replaceWaypoints(waypointIndex, waypointIndex, [])
|
||||
);
|
||||
},
|
||||
setStyleToSelection: (style: LineStyleExtension) => {
|
||||
if (get(selection).size === 0) {
|
||||
return;
|
||||
}
|
||||
fileActionManager.applyGlobal((draft) => {
|
||||
selection.applyToOrderedSelectedItemsFromFile((fileId, level, items) => {
|
||||
let file = draft.get(fileId);
|
||||
if (file && (level === ListLevel.FILE || level === ListLevel.TRACK)) {
|
||||
if (level === ListLevel.FILE) {
|
||||
file.setStyle(style);
|
||||
} else if (level === ListLevel.TRACK) {
|
||||
if (items.length === file.trk.length) {
|
||||
file.setStyle(style);
|
||||
} else {
|
||||
for (let item of items) {
|
||||
let trackIndex = (item as ListTrackItem).getTrackIndex();
|
||||
file.trk[trackIndex].setStyle(style);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
setHiddenToSelection: (hidden: boolean) => {
|
||||
if (get(selection).size === 0) {
|
||||
return;
|
||||
}
|
||||
fileActionManager.applyGlobal((draft) => {
|
||||
selection.applyToOrderedSelectedItemsFromFile((fileId, level, items) => {
|
||||
let file = draft.get(fileId);
|
||||
if (file) {
|
||||
if (level === ListLevel.FILE) {
|
||||
file.setHidden(hidden);
|
||||
} else if (level === ListLevel.TRACK) {
|
||||
let trackIndices = items.map((item) =>
|
||||
(item as ListTrackItem).getTrackIndex()
|
||||
);
|
||||
file.setHidden(hidden, trackIndices);
|
||||
} else if (level === ListLevel.SEGMENT) {
|
||||
let trackIndices = [(items[0] as ListTrackSegmentItem).getTrackIndex()];
|
||||
let segmentIndices = items.map((item) =>
|
||||
(item as ListTrackSegmentItem).getSegmentIndex()
|
||||
);
|
||||
file.setHidden(hidden, trackIndices, segmentIndices);
|
||||
} else if (level === ListLevel.WAYPOINTS) {
|
||||
file.setHiddenWaypoints(hidden);
|
||||
} else if (level === ListLevel.WAYPOINT) {
|
||||
let waypointIndices = items.map((item) =>
|
||||
(item as ListWaypointItem).getWaypointIndex()
|
||||
);
|
||||
file.setHiddenWaypoints(hidden, waypointIndices);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
deleteSelection: () => {
|
||||
if (get(selection).size === 0) {
|
||||
return;
|
||||
}
|
||||
fileActionManager.applyGlobal((draft) => {
|
||||
selection.applyToOrderedSelectedItemsFromFile((fileId, level, items) => {
|
||||
if (level === ListLevel.FILE) {
|
||||
draft.delete(fileId);
|
||||
} else {
|
||||
let file = draft.get(fileId);
|
||||
if (file) {
|
||||
if (level === ListLevel.TRACK) {
|
||||
for (let item of items) {
|
||||
let trackIndex = (item as ListTrackItem).getTrackIndex();
|
||||
file.replaceTracks(trackIndex, trackIndex, []);
|
||||
}
|
||||
} else if (level === ListLevel.SEGMENT) {
|
||||
for (let item of items) {
|
||||
let trackIndex = (item as ListTrackSegmentItem).getTrackIndex();
|
||||
let segmentIndex = (item as ListTrackSegmentItem).getSegmentIndex();
|
||||
file.replaceTrackSegments(
|
||||
trackIndex,
|
||||
segmentIndex,
|
||||
segmentIndex,
|
||||
[]
|
||||
);
|
||||
}
|
||||
} else if (level === ListLevel.WAYPOINTS) {
|
||||
file.replaceWaypoints(0, file.wpt.length - 1, []);
|
||||
} else if (level === ListLevel.WAYPOINT) {
|
||||
for (let item of items) {
|
||||
let waypointIndex = (item as ListWaypointItem).getWaypointIndex();
|
||||
file.replaceWaypoints(waypointIndex, waypointIndex, []);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
addElevationToSelection: async () => {
|
||||
if (get(selection).size === 0) {
|
||||
return;
|
||||
@@ -799,19 +554,4 @@ export const fileActions = {
|
||||
});
|
||||
});
|
||||
},
|
||||
deleteSelectedFiles: () => {
|
||||
if (get(selection).size === 0) {
|
||||
return;
|
||||
}
|
||||
fileActionManager.applyGlobal((draft) => {
|
||||
selection.applyToOrderedSelectedItemsFromFile((fileId, level, items) => {
|
||||
draft.delete(fileId);
|
||||
});
|
||||
});
|
||||
},
|
||||
deleteAllFiles: () => {
|
||||
fileActionManager.applyGlobal((draft) => {
|
||||
draft.clear();
|
||||
});
|
||||
},
|
||||
};
|
||||
Reference in new issue
Block a user