Skip to content

Commit 8502216

Browse files
committed
added layers for points
1 parent 0942839 commit 8502216

23 files changed

Lines changed: 1308 additions & 278 deletions

assets/icons/tabler/copy.svg

Lines changed: 20 additions & 0 deletions
Loading

assets/icons/tabler/eye-x.svg

Lines changed: 22 additions & 0 deletions
Loading

assets/icons/tabler/eye.svg

Lines changed: 20 additions & 0 deletions
Loading

assets/icons/tabler/plus.svg

Lines changed: 20 additions & 0 deletions
Loading

assets/icons/tabler/trash.svg

Lines changed: 23 additions & 0 deletions
Loading

src/app.rs

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ mod bootstrap;
2222
mod layout;
2323
mod model_catalog;
2424
mod panel_state;
25+
mod point_layers;
2526
mod state;
2627
mod status;
2728
mod style;
@@ -52,12 +53,13 @@ use self::i18n::file_import_icon_image;
5253
use self::i18n::{
5354
actions_icon_image, center_origin_icon_image, clear_icon_image, clipboard_import_icon_image,
5455
family_label, fit_icon_image, fit_to_content_icon_image, github_mark_image,
55-
language_flag_image, model_choice_label, open_formula_icon_image,
56-
optimization_loss_metric_label, origin_bottom_left_icon_image, panels_icon_image,
57-
param_init_method_disabled_label, param_init_method_label, param_init_method_name_en,
58-
redo_icon_image, replay_pause_icon_image, replay_play_icon_image, reset_icon_image,
59-
spline_extrapolation_label, spline_knot_strategy_label, spray_brush_label, stop_icon_image,
60-
tool_icon_image, tr, undo_icon_image, view_icon_image,
56+
language_flag_image, layer_delete_icon_image, layer_duplicate_icon_image,
57+
layer_hidden_icon_image, layer_new_icon_image, layer_visible_icon_image, model_choice_label,
58+
open_formula_icon_image, optimization_loss_metric_label, origin_bottom_left_icon_image,
59+
panels_icon_image, param_init_method_disabled_label, param_init_method_label,
60+
param_init_method_name_en, redo_icon_image, replay_pause_icon_image, replay_play_icon_image,
61+
reset_icon_image, spline_extrapolation_label, spline_knot_strategy_label, spray_brush_label,
62+
stop_icon_image, tool_icon_image, tr, undo_icon_image, view_icon_image,
6163
};
6264
use self::model_catalog::{
6365
ModelChoice, ModelGroup, ResolvedModel, model_group, model_group_label,
@@ -78,7 +80,11 @@ use self::param_init::{
7880
rational_family,
7981
};
8082
use self::plot_utils::{fit_bounds_for_content, plot_domain};
81-
use self::points_state::{ParsedPointsCache, PointsEditorState};
83+
use self::point_layers::{PointLayer, PointLayerId, PointLayersState};
84+
use self::points_state::{
85+
ParsedPointsCache, PointsEditorState, points_editor_cache_with_policy,
86+
set_points_editor_cache_from_valid_points,
87+
};
8288
use self::points_text::{
8389
parse_f64, parse_points_from_clipboard_text, parse_points_text_cache, points_to_text,
8490
};
@@ -145,6 +151,7 @@ const DIAGNOSTICS_PANEL_DEFAULT_HEIGHT: f32 = 230.0;
145151
const DIAGNOSTICS_PANEL_MIN_HEIGHT: f32 = 120.0;
146152
const LEFT_PANEL_DEFAULT_WIDTH: f32 = 320.0;
147153
const LEFT_PANEL_MIN_WIDTH: f32 = 320.0;
154+
const LEFT_PANEL_MAX_WIDTH: f32 = 460.0;
148155
const RIGHT_PANEL_DEFAULT_WIDTH: f32 = 280.0;
149156
const RIGHT_PANEL_MIN_WIDTH: f32 = 280.0;
150157
const POINTS_PARSE_DEBOUNCE_MS: u64 = 180;

src/app/bootstrap.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ impl Default for CurveFitApp {
2828
let default_adam = AdamConfig::default();
2929

3030
Self {
31-
points: PointsEditorState::default(),
31+
point_layers: PointLayersState::default(),
3232
#[cfg(not(target_arch = "wasm32"))]
3333
points_file_import_dialog: FileDialog::new()
3434
.title("Import points from file")

src/app/clipboard_import.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ impl CurveFitApp {
185185
) -> Result<usize, String> {
186186
let points = parse_points_from_clipboard_text(text)?;
187187
let imported_count = points.len();
188-
self.write_points_text(&points, true);
188+
self.create_point_layer_from_points(&points);
189189
Ok(imported_count)
190190
}
191191

src/app/file_import.rs

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -467,48 +467,49 @@ mod tests {
467467
fn file_import_replaces_points_text_pushes_undo_and_clears_redo() {
468468
let previous_text = "0 1\n1 2\n";
469469
let mut app = CurveFitApp {
470-
points: super::PointsEditorState {
471-
text: previous_text.to_string(),
472-
redo_stack: vec!["stale redo entry".to_string()],
473-
..Default::default()
474-
},
475470
status: Some(StatusMessage::Error(format!(
476471
"{}previous error",
477472
super::FILE_IMPORT_ERROR_PREFIX
478473
))),
479474
..Default::default()
480475
};
476+
app.selected_layer_mut().points = super::PointsEditorState {
477+
text: previous_text.to_string(),
478+
redo_stack: vec!["stale redo entry".to_string()],
479+
..Default::default()
480+
};
481481
let path = write_temp_file("csv", b"10;20\n30;40\n");
482482

483483
app.handle_points_file_import_path(&path);
484484
cleanup_temp_file(&path);
485485

486486
assert_eq!(
487-
app.points.text,
487+
app.selected_points_editor().text,
488488
"10.00000000 20.00000000\n30.00000000 40.00000000\n"
489489
);
490-
assert_eq!(app.points.undo_stack, vec![previous_text.to_string()]);
491-
assert!(app.points.redo_stack.is_empty());
490+
assert_eq!(
491+
app.selected_points_editor().undo_stack,
492+
vec![previous_text.to_string()]
493+
);
494+
assert!(app.selected_points_editor().redo_stack.is_empty());
492495
assert!(matches!(app.status, Some(StatusMessage::Ready)));
493496
}
494497

495498
#[test]
496499
fn file_import_error_keeps_existing_points_text() {
497500
let previous_text = "0 1\n1 2\n";
498-
let mut app = CurveFitApp {
499-
points: super::PointsEditorState {
500-
text: previous_text.to_string(),
501-
..Default::default()
502-
},
501+
let mut app = CurveFitApp::default();
502+
app.selected_layer_mut().points = super::PointsEditorState {
503+
text: previous_text.to_string(),
503504
..Default::default()
504505
};
505506
let path = write_temp_file("csv", b"1,2,3\n");
506507

507508
app.handle_points_file_import_path(&path);
508509
cleanup_temp_file(&path);
509510

510-
assert_eq!(app.points.text, previous_text);
511-
assert!(app.points.undo_stack.is_empty());
511+
assert_eq!(app.selected_points_editor().text, previous_text);
512+
assert!(app.selected_points_editor().undo_stack.is_empty());
512513
assert!(matches!(
513514
app.status.as_ref(),
514515
Some(StatusMessage::Error(message)) if message.starts_with(super::FILE_IMPORT_ERROR_PREFIX)

src/app/fit_worker.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -765,7 +765,7 @@ impl CurveFitApp {
765765
self.last_right_panel_fit_snapshot = Some(self.capture_right_panel_fit_snapshot());
766766
self.auto_refit_pending_rerun = false;
767767

768-
let points = match self.parse_points_strict() {
768+
let points = match self.parse_visible_points_strict() {
769769
Ok(points) => points,
770770
Err(error) => {
771771
self.status = Some(StatusMessage::Error(error));

0 commit comments

Comments
 (0)