use serde::{Deserialize, Serialize};
use crate::coord::{CanvasRect, WindowRect};
use crate::document::filter::{Filter, FilterEntityRegistration, FilterKind};
use crate::document::layer_kind::{IdMap, PixelBlobSpec, SerializedEntity};
use crate::format::error::LoadError;
use crate::format::manifest::{texture_format_to_str, ManifestPixelRef};
use crate::layer::{LayerId, NodeCommon, PixelBuffer};
pub struct SelectionCpuCache {
pub data: Option<Vec<u8>>,
}
impl SelectionCpuCache {
pub fn new() -> Self {
SelectionCpuCache { data: None }
}
pub fn set(&mut self, data: Vec<u8>) {
self.data = Some(data);
}
pub fn invalidate(&mut self) {
self.data = None;
}
}
impl Default for SelectionCpuCache {
fn default() -> Self {
Self::new()
}
}
pub struct SelectionFilter {
pub pixels: PixelBuffer,
pub cpu_cache: SelectionCpuCache,
pub pixel_bounds: Option<WindowRect>,
}
impl SelectionFilter {
pub fn new(bounds: CanvasRect) -> Self {
SelectionFilter {
pixels: PixelBuffer::new(bounds, wgpu::TextureFormat::R8Unorm),
cpu_cache: SelectionCpuCache::new(),
pixel_bounds: None,
}
}
}
pub const TYPE_ID: &str = "selection";
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
struct SelectionBody {
name: String,
visible: bool,
locked: bool,
pixels: ManifestPixelRef,
}
pub fn register() -> FilterEntityRegistration {
FilterEntityRegistration {
type_id: TYPE_ID,
display_name: "Selection",
serialize,
deserialize,
remap_ids,
}
}
fn serialize(filter: &Filter) -> SerializedEntity {
let sel = match &filter.kind {
FilterKind::Selection(s) => s,
_ => panic!("selection::serialize received non-selection Filter"),
};
let blob_path = "selection.pixels".to_string();
let pixels = ManifestPixelRef {
format: texture_format_to_str(sel.pixels.format).to_string(),
pixels: blob_path.clone(),
bounds: sel.pixels.bounds,
};
let body = SelectionBody {
name: filter.common.name.clone(),
visible: filter.common.visible,
locked: filter.common.locked,
pixels: pixels.clone(),
};
SerializedEntity {
body: serde_json::to_value(&body).expect("derived serde for SelectionBody is infallible"),
pixel_blobs: vec![PixelBlobSpec {
blob_key: blob_path,
source_node_id: filter.id,
pixels,
}],
}
}
fn deserialize(body: &serde_json::Value, id: LayerId) -> Result<Filter, LoadError> {
let body: SelectionBody =
serde_json::from_value(body.clone()).map_err(|e| LoadError::CorruptManifest {
reason: format!("selection body: {e}"),
})?;
Ok(Filter {
id,
common: NodeCommon {
name: body.name,
visible: body.visible,
locked: body.locked,
},
kind: FilterKind::Selection(SelectionFilter {
pixels: PixelBuffer::new(body.pixels.bounds, wgpu::TextureFormat::R8Unorm),
cpu_cache: SelectionCpuCache::new(),
pixel_bounds: None,
}),
})
}
fn remap_ids(_modifier: &mut Filter, _id_map: &IdMap) {
}