use super::super::Render; use crate::coords::cms::CMS; use crate::pipeline::element::{self, Element, ElementID, Target, TargetType}; use crate::pipeline::offscreen_renderer::CanvasWrapper; use crate::{coords::Range, widgets::widget::Widget}; use chrono::{prelude::*, DateTime}; use femtovg::{renderer::OpenGl, Canvas, ImageId}; use std::{ cell::{Ref, RefCell}, fmt::Debug, future::Future, pin::Pin, sync::{Arc, Mutex}, }; use core_extensions::SelfOps; use crate::errors::PipelineError; type PrepareFunc = Arc< Mutex< Option< Box>, CMS) -> Target + Sync + Send>, >, >, >; type DrawFunc = Arc; pub type LayerImplSync = Arc>>; #[derive(Clone)] pub enum AssoElement { TimeSeries(Arc>), Instant(element::InstantElement), Test } #[derive(Clone)] pub struct Layer { pub visiable: bool, pub alpha: f32, pub name: String, associated_element: AssoElement, time: Option>, } impl Debug for Layer { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("Layer") .field("visiable", &self.visiable) .finish() } } pub trait LayerImpl: Debug { fn draw(&self, canvas: &mut Canvas, cms: &CMS) -> Option; } impl Layer { pub fn new(visiable: bool, layer_name: String, element: AssoElement) -> Self { Layer { alpha: 1.0, visiable, name: layer_name, associated_element: element, time: None, } } pub fn set_time(&mut self, time: DateTime) { self.time = Some(time); } pub fn draw(&mut self, render: &Render, window_size: (f32, f32)) -> Result<(), PipelineError> { if self.visiable { match self.associated_element{ AssoElement::Instant(ref mut e) => { e.render(render); } AssoElement::TimeSeries(ref e) => { let mut e = e.lock().unwrap(); let mut buffer = e.buffer.lock().unwrap(); let mut result = buffer.get_mut(&self.time.unwrap()).map(|x| x.as_mut()); if result.is_none(){ return Ok(()) ; } if let Some(result) = result.unwrap(){ let target = result.get_mut_target(); let mut canvas = render.get_canvas(); let mut canvas = canvas.as_mut().unwrap(); let (ox, oy) = target.origin(render); let (x, y) = target.size(render); let result_id = match target.target { TargetType::ImageId(id) => id, TargetType::Mem(ref mem) => { let converted = canvas .load_image_mem(mem, femtovg::ImageFlags::empty()) .unwrap(); target.set_target(TargetType::ImageId(converted)); converted } }; let paint = femtovg::Paint::image(result_id, ox, oy, x, y, 0.0, self.alpha); let mut path = femtovg::Path::new(); path.rect(ox, oy, x, y); canvas.fill_path(&path, &paint); } } _ => {} } return Ok(()); } Ok(()) } pub fn get_thumbnail(&self) -> Option { None } pub fn set_alpha(&mut self, alpha: f32) { self.alpha = alpha; } pub fn change_visiable(&mut self, visiable: bool) { self.visiable = visiable; } pub fn pop_associated_element(&mut self) -> AssoElement { std::mem::replace(&mut self.associated_element, AssoElement::Test) } pub fn get_associated_element(&self) -> &AssoElement { &self.associated_element } pub fn set_associated_element(&mut self, element: AssoElement) { self.associated_element = element; } }