feat(gui): implement selection mask state and vector editing functionality
- Add `selection/state.rs` to manage selection masks, including combining masks and calculating bounds. - Introduce `vector_edit.rs` for vector shape manipulation, handling drag sessions, and hit testing for handles. - Create `feature_scorecard.rs` to ensure stable feature identifiers and regression gates for GUI components. - Implement raster behavior tests in `raster_test.rs` to validate gradient application against masks.
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
//! Tests for selection types: SelectionTransform, TransformHandle, CropState.
|
||||
|
||||
use hcie_iced_gui::selection::{CropState, SelectionTransform, TransformHandle};
|
||||
use hcie_iced_gui::selection::clipboard::centered_transform;
|
||||
use hcie_iced_gui::selection::state::{combine_masks, mask_bounds, selected_spans};
|
||||
use hcie_iced_gui::selection::{CropState, SelectionMode, SelectionTransform, TransformHandle};
|
||||
|
||||
#[test]
|
||||
fn test_selection_transform_is_empty() {
|
||||
@@ -70,3 +72,53 @@ fn test_transform_handle_cursor_hints() {
|
||||
assert_eq!(TransformHandle::TopLeft.cursor_hint(), "nwse-resize");
|
||||
assert_eq!(TransformHandle::Rotate.cursor_hint(), "crosshair");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn selection_modes_combine_alpha_without_losing_soft_edges() {
|
||||
let old = [0, 64, 255, 255];
|
||||
let new = [255, 128, 64, 0];
|
||||
assert_eq!(combine_masks(Some(&old), &new, SelectionMode::Replace), new);
|
||||
assert_eq!(
|
||||
combine_masks(Some(&old), &new, SelectionMode::Add),
|
||||
[255, 128, 255, 255]
|
||||
);
|
||||
assert_eq!(
|
||||
combine_masks(Some(&old), &new, SelectionMode::Subtract),
|
||||
[0, 0, 191, 255]
|
||||
);
|
||||
assert_eq!(
|
||||
combine_masks(Some(&old), &new, SelectionMode::Intersect),
|
||||
[0, 64, 64, 0]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn irregular_mask_bounds_and_fill_spans_are_exact() {
|
||||
let mask = [0, 255, 0, 0, 255, 255, 0, 0, 0, 255, 0, 0];
|
||||
assert_eq!(mask_bounds(&mask, 4, 3), Some((0, 0, 2, 3)));
|
||||
assert_eq!(
|
||||
selected_spans(&mask, 4, 3),
|
||||
vec![(1, 0, 2), (0, 1, 2), (1, 2, 2)]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn crop_clamps_drag_and_cancel_restores_idle_state() {
|
||||
let mut crop = CropState::default();
|
||||
crop.start_drag_clamped(-20.0, 5.0, 100, 80);
|
||||
crop.update_drag(140.0, 120.0);
|
||||
assert_eq!(crop.rect, Some((0.0, 5.0, 100.0, 75.0)));
|
||||
crop.cancel();
|
||||
assert_eq!(crop.canvas_size, None);
|
||||
assert!(!crop.active);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn clipboard_transform_is_centered_and_transform_geometry_is_safe() {
|
||||
let mut transform = centered_transform(vec![255; 8 * 4 * 4], 8, 4, 100, 50).unwrap();
|
||||
assert_eq!(transform.pos, iced::Vector::new(46.0, 23.0));
|
||||
transform.size = iced::Vector::new(-20.0, f32::NAN);
|
||||
transform.sanitize_geometry(true);
|
||||
assert!(transform.size.x > 0.0 && transform.size.y > 0.0);
|
||||
assert!((transform.size.x / transform.size.y - 2.0).abs() < 0.001);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user