mirror of
https://github.com/gpxstudio/gpx.studio.git
synced 2026-11-01 20:19:39 +00:00
Migration to new Rust-based engine (#401)
* wasm first steps * parsing start * parsing continued * progress * progress * progress * progress * progress * progress * progress * progress * fixes * reorganize * change type * fix * progress * refactoring * progress * progress * progress * keep style info * progress * progress * remove (copy) in name * progress * merge methods into 1 * splice * progress * progress * progress * cleaning * progress * progress * progress * visibility * progress * progress * progress * progress * progress * fixes * progress * fix markers * fix * progress * progress * progress * progress * progress * progress * small fix * use engine info * fix popups * small fix * progress * progress * progress * clean tool * handle self closing elements * reduce data exchanges across boundary * copy on wasm side to avoid any data corruption * speed fix * routing * refactoring * reverse * reverse * crop * split * merge * progress * time tool * fix bounds for waypoints * reduce * fix reactivity * handle corrupt time data * export * progress * remove gpx js package * remove todo * update readme * cleaning * progress * fix link fields * remove unused fields * refactoring and tests * import and export of routes, ref #192 * per-chunk categories storage * cross-tab sync * outdated state * refactoring * reorder methods * refactoring * fix * improve flow * renaming * progress * progress * fix * progress * per file history * keep original flag * use history variant * fix * progress * file explorer * progress * fix * sticky folders * improved sticky folders * fix sortable * fix sortable * fix * fix tab size * no file delete on desktop * fix routing on other file * fix sorting * remember language * open links in browser * commit missing changes * avoid selecting on resize * clarify filename * explorer actions * fix folder styling * drop anywhere in folder * cleaning * fixes * remove focus-ring * full screen * small fix * consistent highlight color * improved preview * performance improvements * sparser data transfers * sparser data transfers * show popup once data is loaded * fix routing control size * fix * sparse desktop build * remove custom ign styles * use new endpoint for openhikingmap * strip native menu * reorder context menu items * route full support * route - track conversion * create route file action * route export, filter out anchors at high zoom level * clarify name handling * move hide & center to view * routes continued * update docs * fix power format, closes #378 * lint fixes * fix display of additional data with gaps, closes #361 * fix linting issues * fix import modules * fix multidrag * change base to resolve * fix type errors * fix layer typings * fix last type error * each keys * improve typings * deploy to cloudflare --------- Co-authored-by: vcoppe <vcoppe@hexaly.com>
This commit is contained in:
1 parent
6a0d434371
commit
8fe7d8d64d
484 files changed
+53949
-41152
No files matched your search
@@ -0,0 +1,239 @@
|
||||
//! The desktop shell of gpx.studio. The engine of the files (`gpx-rs/engine`) runs in this
|
||||
//! process, and the frontend talks to it through the commands of `commands`.
|
||||
|
||||
mod bytes;
|
||||
mod commands;
|
||||
mod state;
|
||||
mod store;
|
||||
mod workspace;
|
||||
|
||||
use commands::*;
|
||||
use tauri::{Emitter, Manager};
|
||||
|
||||
/// The engine of the app: each file has its own history, so that undoing only concerns the
|
||||
/// selected files, and opening or closing a file is not something to undo.
|
||||
pub(crate) type Engine = gpx_engine::Engine<gpx_engine::PerFileHistory>;
|
||||
|
||||
/// The GPX files among what the system gave to the app (the arguments of the command line, when a
|
||||
/// file is opened with it).
|
||||
fn gpx_paths(arguments: impl IntoIterator<Item = String>) -> Vec<std::path::PathBuf> {
|
||||
arguments
|
||||
.into_iter()
|
||||
.map(std::path::PathBuf::from)
|
||||
.filter(|path| {
|
||||
path.is_file()
|
||||
&& path
|
||||
.extension()
|
||||
.is_some_and(|extension| extension.eq_ignore_ascii_case("gpx"))
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
||||
pub fn run() {
|
||||
let builder = tauri::Builder::default();
|
||||
// a single instance of the app: starting it again shows the one that runs (it has to be the
|
||||
// first plugin)
|
||||
#[cfg(desktop)]
|
||||
let builder = builder.plugin(tauri_plugin_single_instance::init(
|
||||
|app, arguments, _directory| {
|
||||
if let Some(window) = app.get_webview_window("main") {
|
||||
let _ = window.unminimize();
|
||||
let _ = window.show();
|
||||
let _ = window.set_focus();
|
||||
}
|
||||
// a file that was opened with the app, while it runs (Windows, Linux)
|
||||
if let Some(state) = app.try_state::<state::AppState>() {
|
||||
state.open_external(gpx_paths(arguments.into_iter().skip(1)));
|
||||
}
|
||||
},
|
||||
));
|
||||
// on macOS, the app has a menu bar of its own (Windows and Linux have none by default)
|
||||
#[cfg(target_os = "macos")]
|
||||
let builder = builder.menu(menu);
|
||||
register_commands(builder)
|
||||
.plugin(tauri_plugin_dialog::init())
|
||||
.plugin(tauri_plugin_opener::init())
|
||||
.setup(|app| {
|
||||
let handle = app.handle().clone();
|
||||
let emit: state::Emit = std::sync::Arc::new(move |event, payload| {
|
||||
let _ = handle.emit(event, payload);
|
||||
});
|
||||
// what the engine holds is kept in the data directory of the app
|
||||
let directory = app.path().app_data_dir()?.join("store");
|
||||
let state = state::AppState::open(directory, emit)?;
|
||||
// a file that was opened with the app, which starts (Windows, Linux)
|
||||
state.open_external(gpx_paths(std::env::args().skip(1)));
|
||||
app.manage(state);
|
||||
Ok(())
|
||||
})
|
||||
.build(tauri::generate_context!())
|
||||
.expect("error while building gpx.studio")
|
||||
.run(|_app, _event| {
|
||||
// a file that was opened with the app (macOS)
|
||||
#[cfg(any(target_os = "macos", target_os = "ios"))]
|
||||
if let tauri::RunEvent::Opened { urls } = _event
|
||||
&& let Some(state) = _app.try_state::<state::AppState>()
|
||||
{
|
||||
let paths = urls.iter().filter_map(|url| url.to_file_path().ok());
|
||||
state.open_external(gpx_paths(
|
||||
paths.map(|path| path.to_string_lossy().into_owned()),
|
||||
));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
fn menu<R: tauri::Runtime>(app: &tauri::AppHandle<R>) -> tauri::Result<tauri::menu::Menu<R>> {
|
||||
use tauri::menu::{AboutMetadata, Menu, PredefinedMenuItem, Submenu};
|
||||
// the name of the product, as macOS would otherwise name the items after the binary
|
||||
let name = app.package_info().name.clone();
|
||||
let about = AboutMetadata {
|
||||
name: Some(name.clone()),
|
||||
..Default::default()
|
||||
};
|
||||
Menu::with_items(
|
||||
app,
|
||||
&[&Submenu::with_items(
|
||||
app,
|
||||
&name,
|
||||
true,
|
||||
&[
|
||||
&PredefinedMenuItem::about(app, Some(&format!("About {name}")), Some(about))?,
|
||||
&PredefinedMenuItem::separator(app)?,
|
||||
&PredefinedMenuItem::quit(app, Some(&format!("Quit {name}")))?,
|
||||
],
|
||||
)?],
|
||||
)
|
||||
}
|
||||
|
||||
/// Gives the builder the commands that reach the engine (which it has to be given as `AppState`).
|
||||
fn register_commands<R: tauri::Runtime>(builder: tauri::Builder<R>) -> tauri::Builder<R> {
|
||||
builder.invoke_handler(tauri::generate_handler![
|
||||
// selection
|
||||
selection::select,
|
||||
selection::select_all,
|
||||
selection::arrow_select,
|
||||
selection::select_routes,
|
||||
selection::select_tracks,
|
||||
selection::select_segments,
|
||||
selection::select_waypoint_group,
|
||||
selection::select_waypoints,
|
||||
// files
|
||||
files::new_file,
|
||||
files::load_files,
|
||||
files::duplicate,
|
||||
files::delete,
|
||||
files::delete_all,
|
||||
files::reorder,
|
||||
files::copy,
|
||||
files::cut,
|
||||
files::paste,
|
||||
files::move_elements,
|
||||
files::undo,
|
||||
files::redo,
|
||||
// edits and tools
|
||||
edit::metadata,
|
||||
edit::style,
|
||||
edit::convert,
|
||||
edit::new_route,
|
||||
edit::new_track,
|
||||
edit::new_track_segment,
|
||||
edit::new_waypoint,
|
||||
edit::move_waypoint,
|
||||
edit::delete_waypoint,
|
||||
edit::update_waypoint,
|
||||
edit::reverse,
|
||||
edit::round_trip,
|
||||
edit::crop,
|
||||
edit::reduce,
|
||||
edit::change_timestamps,
|
||||
edit::create_artificial_timestamps,
|
||||
edit::merge,
|
||||
edit::extract,
|
||||
edit::elevation,
|
||||
edit::clean,
|
||||
edit::route,
|
||||
edit::insert_anchor,
|
||||
edit::change_loop_start,
|
||||
edit::split,
|
||||
// queries
|
||||
queries::file_order,
|
||||
queries::file_structure,
|
||||
queries::file_statistics,
|
||||
queries::selection,
|
||||
queries::clipboard,
|
||||
queries::can_undo,
|
||||
queries::can_redo,
|
||||
queries::can_paste,
|
||||
queries::waypoint,
|
||||
queries::trackpoint,
|
||||
queries::export_file,
|
||||
queries::exportable_data,
|
||||
queries::reduction_distances,
|
||||
queries::segment_coordinates,
|
||||
queries::waypoint_coordinates,
|
||||
// statistics
|
||||
statistics::total_distance,
|
||||
statistics::slope_segment_starts,
|
||||
statistics::slope_segment_slopes,
|
||||
statistics::lng,
|
||||
statistics::lat,
|
||||
statistics::ele,
|
||||
statistics::speed,
|
||||
statistics::hr,
|
||||
statistics::cad,
|
||||
statistics::atemp,
|
||||
statistics::power,
|
||||
statistics::selection_point,
|
||||
statistics::selection_statistics,
|
||||
statistics::slice_statistics,
|
||||
statistics::surface_starts,
|
||||
statistics::surface_values,
|
||||
statistics::highway_starts,
|
||||
statistics::highway_values,
|
||||
statistics::sac_scale_starts,
|
||||
statistics::sac_scale_values,
|
||||
statistics::mtb_scale_starts,
|
||||
statistics::mtb_scale_values,
|
||||
statistics::surfaces,
|
||||
statistics::highways,
|
||||
statistics::sac_scales,
|
||||
statistics::mtb_scales,
|
||||
statistics::anchor_indices,
|
||||
statistics::anchor_zooms,
|
||||
statistics::segment_starts,
|
||||
statistics::segment_ids,
|
||||
statistics::routing_revision,
|
||||
// storage
|
||||
storage::open_storage,
|
||||
storage::flush_storage,
|
||||
storage::sync_storage,
|
||||
storage::set_setting,
|
||||
storage::delete_setting,
|
||||
// the file system
|
||||
disk::workspace_state,
|
||||
disk::open_files,
|
||||
disk::open_paths,
|
||||
disk::keep_files,
|
||||
disk::open_folder,
|
||||
disk::close_folder,
|
||||
disk::close_files,
|
||||
disk::save_files,
|
||||
disk::save_file_as,
|
||||
disk::reload_files,
|
||||
disk::export_files,
|
||||
disk::list_folder,
|
||||
disk::create_folder,
|
||||
disk::rename_path,
|
||||
disk::rename_file,
|
||||
disk::move_paths,
|
||||
disk::delete_paths,
|
||||
// the system
|
||||
system::open_url,
|
||||
system::reveal_path,
|
||||
])
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
Reference in new issue
Block a user