mirror of
https://github.com/gpxstudio/gpx.studio.git
synced 2026-10-06 22:04:06 +00:00
progress
This commit is contained in:
@@ -3,9 +3,11 @@ mod edit_waypoint_chunks;
|
|||||||
mod insert_waypoints;
|
mod insert_waypoints;
|
||||||
mod produce;
|
mod produce;
|
||||||
mod update_selected;
|
mod update_selected;
|
||||||
|
mod update_waypoint;
|
||||||
|
|
||||||
pub use copy::*;
|
pub use copy::*;
|
||||||
pub use edit_waypoint_chunks::*;
|
pub use edit_waypoint_chunks::*;
|
||||||
pub use insert_waypoints::*;
|
pub use insert_waypoints::*;
|
||||||
pub use produce::*;
|
pub use produce::*;
|
||||||
pub use update_selected::*;
|
pub use update_selected::*;
|
||||||
|
pub use update_waypoint::*;
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
use crate::{CommandError, FileId, State, Waypoint, WaypointId, edit_waypoint_chunks};
|
||||||
|
|
||||||
|
/// Changes one waypoint of a file with `f`, whatever is selected. Nothing to do if the file or
|
||||||
|
/// the waypoint does not exist.
|
||||||
|
pub fn update_waypoint(
|
||||||
|
state: &mut State,
|
||||||
|
file_id: FileId,
|
||||||
|
waypoint_id: WaypointId,
|
||||||
|
f: impl Fn(&mut Waypoint),
|
||||||
|
) -> Result<(), CommandError> {
|
||||||
|
let file = state.files.get(&file_id).ok_or(CommandError::NothingToDo)?;
|
||||||
|
let mut file = (**file).clone();
|
||||||
|
let changed = edit_waypoint_chunks(
|
||||||
|
&mut file,
|
||||||
|
|wpt| wpt.id == waypoint_id,
|
||||||
|
|wpts| {
|
||||||
|
wpts.iter_mut()
|
||||||
|
.filter(|wpt| wpt.id == waypoint_id)
|
||||||
|
.for_each(&f);
|
||||||
|
true
|
||||||
|
},
|
||||||
|
);
|
||||||
|
if !changed {
|
||||||
|
return Err(CommandError::NothingToDo);
|
||||||
|
}
|
||||||
|
state.files.insert(file_id, Rc::new(file));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
@@ -1,11 +1,12 @@
|
|||||||
use crate::{
|
use crate::{Apply, CommandError, FileId, State, WaypointId, set_waypoint_fields, update_waypoint};
|
||||||
Apply, CommandError, Edit, Editor, State, Waypoint, set_waypoint_fields, update_selected,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Changes the selected waypoints (what the form of the waypoint tool does): their name,
|
/// Changes a waypoint of a file, whatever is selected (what the form of the waypoint tool does):
|
||||||
/// description, icon, link, position and elevation. The strings that are empty remove the field.
|
/// its name, description, icon, link, position and elevation. The strings that are empty remove
|
||||||
|
/// the field.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct EditWaypoint<'a> {
|
pub struct EditWaypoint<'a> {
|
||||||
|
pub file_id: FileId,
|
||||||
|
pub waypoint_id: WaypointId,
|
||||||
pub lng: f64,
|
pub lng: f64,
|
||||||
pub lat: f64,
|
pub lat: f64,
|
||||||
pub ele: f64,
|
pub ele: f64,
|
||||||
@@ -16,38 +17,32 @@ pub struct EditWaypoint<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Apply for EditWaypoint<'_> {
|
impl Apply for EditWaypoint<'_> {
|
||||||
fn apply(mut self, state: &mut State) -> Result<(), CommandError> {
|
fn apply(self, state: &mut State) -> Result<(), CommandError> {
|
||||||
update_selected(state, &mut self);
|
update_waypoint(state, self.file_id, self.waypoint_id, |wpt| {
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Editor for EditWaypoint<'_> {
|
|
||||||
fn waypoint(&mut self, waypoint: &mut Waypoint) -> Edit {
|
|
||||||
set_waypoint_fields(
|
set_waypoint_fields(
|
||||||
waypoint,
|
wpt,
|
||||||
(self.lng, self.lat, self.ele),
|
(self.lng, self.lat, self.ele),
|
||||||
self.name,
|
self.name,
|
||||||
self.desc,
|
self.desc,
|
||||||
self.icon,
|
self.icon,
|
||||||
self.link,
|
self.link,
|
||||||
);
|
)
|
||||||
Edit::Changed
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::{collections::HashSet, rc::Rc};
|
use std::rc::Rc;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
File, Link, Selection, WaypointChunk, engine::command::fixture::Fixture, waypoint_ids,
|
File, Link, Waypoint, WaypointChunk, engine::command::fixture::Fixture, waypoint_ids,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_edit_the_selected_waypoint() {
|
fn test_edit_the_given_waypoint() {
|
||||||
let mut fx = Fixture::default();
|
let mut fx = Fixture::default();
|
||||||
let mut file = File::default();
|
let mut file = File::default();
|
||||||
file.wpt.push(Rc::new(WaypointChunk {
|
file.wpt.push(Rc::new(WaypointChunk {
|
||||||
@@ -73,12 +68,10 @@ mod tests {
|
|||||||
let id = file.id;
|
let id = file.id;
|
||||||
let ids: Vec<_> = waypoint_ids(&file).collect();
|
let ids: Vec<_> = waypoint_ids(&file).collect();
|
||||||
fx.files.insert(id, Rc::new(file));
|
fx.files.insert(id, Rc::new(file));
|
||||||
fx.selection = Selection::Waypoint {
|
|
||||||
file_id: id,
|
|
||||||
wpt_ids: HashSet::from([ids[0]]),
|
|
||||||
};
|
|
||||||
|
|
||||||
EditWaypoint {
|
EditWaypoint {
|
||||||
|
file_id: id,
|
||||||
|
waypoint_id: ids[0],
|
||||||
lng: 4.5,
|
lng: 4.5,
|
||||||
lat: 50.5,
|
lat: 50.5,
|
||||||
ele: 12.0,
|
ele: 12.0,
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
use std::rc::Rc;
|
use crate::{Apply, CommandError, FileId, LngLat, State, WaypointId, update_waypoint};
|
||||||
|
|
||||||
use crate::{Apply, CommandError, FileId, LngLat, State, WaypointId, edit_waypoint_chunks};
|
|
||||||
|
|
||||||
/// Moves a waypoint of a file, whatever is selected (what a drag does): only its position and
|
/// Moves a waypoint of a file, whatever is selected (what a drag does): only its position and
|
||||||
/// elevation change.
|
/// elevation change.
|
||||||
@@ -15,30 +13,13 @@ pub struct MoveWaypoint {
|
|||||||
|
|
||||||
impl Apply for MoveWaypoint {
|
impl Apply for MoveWaypoint {
|
||||||
fn apply(self, state: &mut State) -> Result<(), CommandError> {
|
fn apply(self, state: &mut State) -> Result<(), CommandError> {
|
||||||
let file = state
|
update_waypoint(state, self.file_id, self.waypoint_id, |wpt| {
|
||||||
.files
|
|
||||||
.get(&self.file_id)
|
|
||||||
.ok_or(CommandError::NothingToDo)?;
|
|
||||||
let mut file = (**file).clone();
|
|
||||||
let changed = edit_waypoint_chunks(
|
|
||||||
&mut file,
|
|
||||||
|wpt| wpt.id == self.waypoint_id,
|
|
||||||
|wpts| {
|
|
||||||
for wpt in wpts.iter_mut().filter(|wpt| wpt.id == self.waypoint_id) {
|
|
||||||
wpt.coordinates = LngLat {
|
wpt.coordinates = LngLat {
|
||||||
lng: self.lng,
|
lng: self.lng,
|
||||||
lat: self.lat,
|
lat: self.lat,
|
||||||
};
|
};
|
||||||
wpt.ele = self.ele;
|
wpt.ele = self.ele;
|
||||||
}
|
})
|
||||||
true
|
|
||||||
},
|
|
||||||
);
|
|
||||||
if !changed {
|
|
||||||
return Err(CommandError::NothingToDo);
|
|
||||||
}
|
|
||||||
state.files.insert(self.file_id, Rc::new(file));
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1188,18 +1188,11 @@ mod tests {
|
|||||||
// the coordinates buffer follows
|
// the coordinates buffer follows
|
||||||
assert_eq!(engine.waypoint_coordinates(&file), &[5.0, 51.0]);
|
assert_eq!(engine.waypoint_coordinates(&file), &[5.0, 51.0]);
|
||||||
|
|
||||||
// editing applies to the selected waypoints
|
|
||||||
select_elements(
|
|
||||||
&mut engine,
|
|
||||||
Selection::Waypoint {
|
|
||||||
file_id: file,
|
|
||||||
wpt_ids: [id].into(),
|
|
||||||
},
|
|
||||||
SelectMode::Replace,
|
|
||||||
);
|
|
||||||
assert!(edit(
|
assert!(edit(
|
||||||
&mut engine,
|
&mut engine,
|
||||||
Command::EditWaypoint(EditWaypoint {
|
Command::EditWaypoint(EditWaypoint {
|
||||||
|
file_id: file,
|
||||||
|
waypoint_id: id,
|
||||||
lng: 6.0,
|
lng: 6.0,
|
||||||
lat: 52.0,
|
lat: 52.0,
|
||||||
ele: 30.0,
|
ele: 30.0,
|
||||||
|
|||||||
+12
-4
@@ -317,10 +317,13 @@ fn parse_waypoint_id(id: &str) -> Option<engine::WaypointId> {
|
|||||||
uuid::Uuid::parse_str(id).ok().map(engine::WaypointId)
|
uuid::Uuid::parse_str(id).ok().map(engine::WaypointId)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Changes the selected waypoints: their name, description, icon, link, position and elevation.
|
/// Changes a waypoint of a file, whatever is selected: its name, description, icon, link, position
|
||||||
/// The strings that are empty remove the field.
|
/// and elevation. The strings that are empty remove the field.
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn update_waypoint(
|
pub fn update_waypoint(
|
||||||
|
file_id: &str,
|
||||||
|
waypoint_id: &str,
|
||||||
lng: f64,
|
lng: f64,
|
||||||
lat: f64,
|
lat: f64,
|
||||||
ele: f64,
|
ele: f64,
|
||||||
@@ -329,7 +332,10 @@ pub fn update_waypoint(
|
|||||||
icon: &str,
|
icon: &str,
|
||||||
link: &str,
|
link: &str,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
edit(Command::EditWaypoint(engine::EditWaypoint {
|
match (parse_file_id(file_id), parse_waypoint_id(waypoint_id)) {
|
||||||
|
(Some(file_id), Some(waypoint_id)) => edit(Command::EditWaypoint(engine::EditWaypoint {
|
||||||
|
file_id,
|
||||||
|
waypoint_id,
|
||||||
lng,
|
lng,
|
||||||
lat,
|
lat,
|
||||||
ele,
|
ele,
|
||||||
@@ -337,7 +343,9 @@ pub fn update_waypoint(
|
|||||||
desc,
|
desc,
|
||||||
icon,
|
icon,
|
||||||
link,
|
link,
|
||||||
}))
|
})),
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
|
|||||||
@@ -99,12 +99,10 @@
|
|||||||
link,
|
link,
|
||||||
};
|
};
|
||||||
if (target) {
|
if (target) {
|
||||||
// the engine changes the selected waypoint
|
engine.updateWaypoint(target.fileId, target.id, waypoint);
|
||||||
await engine.selectWaypoints(target.fileId, [target.id]);
|
|
||||||
await engine.updateWaypoint(waypoint);
|
|
||||||
} else {
|
} else {
|
||||||
// it goes in the selected files
|
// it goes in the selected files
|
||||||
await engine.newWaypoint(waypoint);
|
engine.newWaypoint(waypoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
reset();
|
reset();
|
||||||
|
|||||||
@@ -449,10 +449,12 @@ class Engine {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Changes the selected waypoints. Empty strings remove the field. */
|
/** Changes a waypoint, selected or not. Empty strings remove the field. */
|
||||||
updateWaypoint(waypoint: NewWaypoint) {
|
updateWaypoint(fileId: string, waypointId: string, waypoint: NewWaypoint) {
|
||||||
return this.run((w) =>
|
return this.run((w) =>
|
||||||
w.update_waypoint(
|
w.update_waypoint(
|
||||||
|
fileId,
|
||||||
|
waypointId,
|
||||||
waypoint.lng,
|
waypoint.lng,
|
||||||
waypoint.lat,
|
waypoint.lat,
|
||||||
waypoint.ele,
|
waypoint.ele,
|
||||||
|
|||||||
Reference in New Issue
Block a user