radar-g/src/widgets/render/interior/layers.rs
2024-03-11 12:03:23 +08:00

145 lines
4.3 KiB
Rust

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<dyn FnOnce(LayerImplSync, Arc<Mutex<CanvasWrapper>>, CMS) -> Target + Sync + Send>,
>,
>,
>;
type DrawFunc = Arc<dyn Fn(&Layer, Render, (f32, f32)) + Send + Sync>;
pub type LayerImplSync = Arc<Mutex<Box<dyn LayerImpl + Send + Sync>>>;
#[derive(Clone)]
pub enum AssoElement {
TimeSeries(Arc<Mutex<element::TimeSeriesElement>>),
Instant(element::InstantElement),
Test
}
#[derive(Clone)]
pub struct Layer {
pub visiable: bool,
pub alpha: f32,
pub name: String,
associated_element: AssoElement,
time: Option<DateTime<Utc>>,
}
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<OpenGl>, cms: &CMS) -> Option<Target>;
}
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<Utc>) {
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<gtk::gdk::Texture> {
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;
}
}