diff --git a/src/components/app.rs b/src/components/app.rs index 6e7d860..eeca4c4 100644 --- a/src/components/app.rs +++ b/src/components/app.rs @@ -187,6 +187,8 @@ impl Component for AppModel { root: &Self::Root, sender: ComponentSender, ) -> ComponentParts { + + let layers = Rc::new(RefCell::new(Vec::with_capacity(20))); let control = ControlPanelModel::builder().launch(0).forward( sender.input_sender(), |msg| match msg { @@ -198,7 +200,7 @@ impl Component for AppModel { ); let render = MonitorModel::builder() - .launch(()) + .launch(layers.clone()) .forward(sender.input_sender(), |a| match a { MonitorOutputMsg::LayerRenderFinished => AppMsg::Close, _ => AppMsg::Close, @@ -224,9 +226,11 @@ impl Component for AppModel { let mut canvas = renderer.create_canvas(); let mut cms_ref = dialog_cms.lock().unwrap(); - let data = element_impl.render(&data,&mut canvas,&mut (*cms_ref)); + let mut data_target = element_impl.render(&data,&mut canvas,&mut (*cms_ref)); + data_target.data = Some(Arc::new(data) as Arc); + let element = Element::create_instant( - InstantElementDrawerType::Prepared(data), + InstantElementDrawerType::Prepared(data_target), dialog_dispatcher.clone(), "New Element".to_string(), ).get_instance(); @@ -246,7 +250,7 @@ impl Component for AppModel { open_dialog: dialog, control, render, - layers: Rc::new(RefCell::new(Vec::with_capacity(20))), + layers , setting, tracker: 0, }; @@ -282,6 +286,7 @@ impl Component for AppModel { } AppMsg::NewLayer(layer) => { (*self.layers).borrow_mut().push(layer); + self.render.sender().send(MonitorInputMsg::RefreshLayerList); } AppMsg::CloseRequest => { relm4::main_application().quit(); @@ -292,6 +297,7 @@ impl Component for AppModel { } _ => {} } + self.update_view(widgets, _sender); } fn update_cmd( diff --git a/src/components/monitor/messages.rs b/src/components/monitor/messages.rs index e504be0..565f570 100644 --- a/src/components/monitor/messages.rs +++ b/src/components/monitor/messages.rs @@ -16,12 +16,14 @@ pub enum MonitorInputMsg { ClearMetaItems, UpdateMetaItem(HashMap), UpdateLayer((String, Box)), + RefreshLayerList, None, } impl Debug for MonitorInputMsg { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { + MonitorInputMsg::RefreshLayerList => write!(f, "MonitorInputMsg::RefreshLayerList"), MonitorInputMsg::NewElement(_) => write!(f, "MonitorInputMsg::NewElement"), MonitorInputMsg::AddLayer(_) => write!(f, "MonitorInputMsg::AddLayer"), MonitorInputMsg::RemoveLayer(_) => write!(f, "MonitorInputMsg::RemoveLayer"), diff --git a/src/components/monitor/monitor.rs b/src/components/monitor/monitor.rs index 00eb81e..b2bbd01 100644 --- a/src/components/monitor/monitor.rs +++ b/src/components/monitor/monitor.rs @@ -50,7 +50,7 @@ pub struct MonitorWidgets { impl Component for MonitorModel { type CommandOutput = MonitorCommand; type Input = MonitorInputMsg; - type Init = (); + type Init = Rc>>; type Output = MonitorOutputMsg; view! { @@ -76,6 +76,7 @@ impl Component for MonitorModel { set_margin_all: 5, #[name="widget_layer"] gtk::Overlay{ + #[name = "renderer"] #[wrap(Some)] set_child = &Render{ // #[track = "model.changed(MonitorModel::new_layer())"] @@ -86,7 +87,8 @@ impl Component for MonitorModel { set_view: model.render_range, connect_render_status_notify[sender] => move |r| { sender.output(MonitorOutputMsg::LayerRenderFinished); - } + }, + set_interior_layers: model.layers.clone(), }, add_overlay=>k::Button{ set_label:"Add", @@ -107,7 +109,8 @@ impl Component for MonitorModel { } } - fn update(&mut self, message: Self::Input, sender: ComponentSender, root: &Self::Root) { + fn update_with_view(&mut self, widgets: &mut Self::Widgets, message: Self::Input, sender: ComponentSender, root: &Self::Root) { + self.reset(); match message { MonitorInputMsg::AddLayer(layer) => { @@ -115,51 +118,10 @@ impl Component for MonitorModel { let raw_id = self.get_new_layer(); self.set_new_layer(*raw_id + 1); self.sidebar.sender().send(SideBarInputMsg::RefreshList); - // let need_prepare = { layer.get_prepare().lock().unwrap().is_some() }; - // { - // let mut layers = self.layers.borrow_mut(); - // if !layers.contains_key(layer.name.as_str()) { - // let mut widgets = layer.widgets.lock().unwrap(); - // if widgets.is_some() { - // let ws = widgets.take().unwrap(); - // ws.into_iter().for_each(|w| { - // sender.input(MonitorInputMsg::AddWidget(w)); - // }); - // } - // } - // } - // if need_prepare { - // sender.oneshot_command(async move { - // let mut back = OffscreenRenderer::new(3000, 3000).unwrap(); - // let canvas = back.create_canvas(); - // let f = { - // let p = layer.get_prepare(); - // let mut _p = p.lock().unwrap(); - // _p.take().unwrap() - // }; - // let imp = layer.get_imp().unwrap(); - // let map: Mapper = Mercator::default().into(); - // let cms = CMS::new(map, (3000.0, 3000.0)); - // let canvas = Arc::new(Mutex::new(canvas)); - // let target = f(imp, canvas, cms); - // layer.set_render_target(target); - // MonitorCommand::NewLayer(layer) - // }); - // } else { - // { - // let mut layers = self.layers.borrow_mut(); - // if layers.contains_key(layer.name.as_str()) { - // let p = layers.get_mut(layer.name.as_str()).unwrap(); - // *p = layer; - // } else { - // layers.insert(layer.name.clone(), layer); - // } - // } - - // let raw_id = self.get_new_layer(); - // self.set_new_layer(*raw_id + 1); - // self.sidebar.sender().send(SideBarInputMsg::RefreshList); - // } + } + MonitorInputMsg::RefreshLayerList => { + self.sidebar.sender().send(SideBarInputMsg::RefreshList); + widgets.renderer.queue_render(); } MonitorInputMsg::AddMetaItem(map) => { self.sidebar.emit(SideBarInputMsg::AddMetaItems(map)) @@ -169,20 +131,6 @@ impl Component for MonitorModel { self.sidebar.emit(SideBarInputMsg::ClearMetaItems); self.sidebar.emit(SideBarInputMsg::AddMetaItems(map)) } - // MonitorInputMsg::RemoveLayer(k) => { - // self.layers.borrow_mut().remove(&k); - // sender - // .output_sender() - // .send(MonitorOutputMsg::LayerRemoved(0)) - // .unwrap(); - // } - // MonitorInputMsg::UpdateLayer((k, f)) => { - // f(&mut (*self.layers.borrow_mut().get_mut(&k).unwrap())); - // sender - // .output_sender() - // .send(MonitorOutputMsg::LayerUpdated(0)) - // .unwrap(); - // } MonitorInputMsg::AddWidget(widget) => match widget.widget_type() { WidgetType::Cairo => { let frame = WidgetFrame::new(); @@ -196,6 +144,8 @@ impl Component for MonitorModel { MonitorInputMsg::None => {} _ => {} } + + self.update_view(widgets, sender); } fn init( @@ -203,9 +153,8 @@ impl Component for MonitorModel { root: &Self::Root, sender: ComponentSender, ) -> ComponentParts { - let layers = Rc::new(RefCell::new(Vec::new())); let sidebar: Controller = SideBarModel::builder() - .launch(layers.clone()) + .launch(init.clone()) .forward(sender.input_sender(), |msg| match msg { SideBarOutputMsg::NewLayer(layer) => MonitorInputMsg::AddLayer(layer), _ => MonitorInputMsg::None, @@ -222,7 +171,7 @@ impl Component for MonitorModel { render_cfg, sidebar_open: true, sidebar_width: 400, - layers: layers, + layers: init, sidebar, tracker: 0, }; diff --git a/src/pipeline/element.rs b/src/pipeline/element.rs index e89e4c1..e45ae7e 100644 --- a/src/pipeline/element.rs +++ b/src/pipeline/element.rs @@ -23,12 +23,14 @@ use std::{ pin::Pin, sync::{Arc, Mutex}, }; +use core_extensions::SelfOps; use radarg_plugin_interface::PluginResult; use tokio::sync::{ oneshot::{channel, Receiver, Sender}, Notify, }; use tracing::Instrument; +use crate::widgets::Render; pub type ElementID = usize; static ELEMENT_ID: AtomicUsize = AtomicUsize::new(0); @@ -36,7 +38,7 @@ static ELEMENT_ID: AtomicUsize = AtomicUsize::new(0); pub type Data = Box; pub type Buffer = Arc, (Option, Option)>>>; -type DrawFunc = Arc>; +type DrawFunc = Rc>; type IResult = Result; #[derive(Debug)] @@ -134,13 +136,31 @@ impl InstantElement { dispatcher, } } - - pub fn render(&self, canvas: &mut CanvasWrapper, cms: &CMS) { + pub fn render(&mut self, render: &Render) { match self.draw_type { InstantElementDrawerType::Draw(ref func) => { - func(canvas, cms); + func(render); + } + InstantElementDrawerType::Prepared(ref 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,1.0 ); + let mut path = femtovg::Path::new(); + path.rect(ox,oy,x,y); + canvas.fill_path(&path, &paint); } - InstantElementDrawerType::Prepared(ref target) => {} } } } @@ -280,13 +300,14 @@ impl RenderResult { } } -#[derive(Clone, Debug, PartialEq, PartialOrd)] +#[derive(Clone, Debug)] pub struct Target { pub target: TargetType, pub thumbnail: Option, pub width: f32, pub height: f32, pub bounds: (Range, Range), + pub data: Option> } #[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord)] @@ -302,6 +323,7 @@ impl Target { height: f32, bounds: (Range, Range), thumbnail: Option, + data: Option>, ) -> Self { Self { target, @@ -309,10 +331,11 @@ impl Target { height, bounds, thumbnail, + data } } - pub fn size(&self, cms: &CMS) -> (f32, f32) { + pub fn size(&self, cms: &Render) -> (f32, f32) { let (x, y) = self.bounds; let p1 = (x.0, y.0); @@ -324,7 +347,7 @@ impl Target { ((x2 - x1).abs(), (y2 - y1).abs()) } - pub fn origin(&self, cms: &CMS) -> (f32, f32) { + pub fn origin(&self, cms: &Render) -> (f32, f32) { let (x, y) = self.bounds; let p1 = (x.0, y.1); cms.map(p1).unwrap() diff --git a/src/pipeline/element_impl.rs b/src/pipeline/element_impl.rs index 6c118d7..538d2e4 100644 --- a/src/pipeline/element_impl.rs +++ b/src/pipeline/element_impl.rs @@ -4,7 +4,7 @@ use crate::data::Radar2d; use crate::pipeline::element::{ElementImpl, Target}; use crate::pipeline::offscreen_renderer::CanvasWrapper; use crate::widgets::predefined::color_mapper::ColorMapper; -use crate::widgets::{LayerImpl, CMS}; +use crate::widgets::{LayerImpl}; use num_traits::{AsPrimitive, FromPrimitive, Num, NumOps}; use std::any::Any; use std::fmt::Debug; diff --git a/src/pipeline/offscreen_renderer.rs b/src/pipeline/offscreen_renderer.rs index f0042ae..39d4867 100644 --- a/src/pipeline/offscreen_renderer.rs +++ b/src/pipeline/offscreen_renderer.rs @@ -1,20 +1,20 @@ - use super::utils::*; +use crate::pipeline::element::Target; use euclid::Size2D; use femtovg::{renderer::OpenGl, Canvas}; use gl; use gl::types::{GLchar, GLenum, GLint, GLuint, GLvoid}; use glow::HasContext; +use std::borrow::{Borrow, BorrowMut}; +use std::fmt::{Debug, Formatter}; use std::num::NonZeroU32; use std::ops::{Deref, DerefMut}; use std::sync::{Mutex, RwLock}; use std::{cell::RefCell, sync::Arc}; -use std::fmt::{Debug, Formatter}; use surfman::{ device, Adapter, Connection, Context, ContextAttributeFlags, Device, Error, GLApi, NativeConnection, NativeDevice, }; -use crate::pipeline::element::Target; pub struct OffscreenRenderer { context: Arc>, @@ -110,8 +110,7 @@ impl OffscreenRenderer { CanvasWrapper::new(canvas) } - pub fn get_img(&self, target: Target) { - } + pub fn get_img(&self, target: Target) {} pub fn get_mem_img(&self) -> Vec { let (w, h) = self.size; @@ -151,7 +150,6 @@ impl Debug for CanvasWrapper { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.debug_struct("CanvasWrapper").finish() } - } impl CanvasWrapper { @@ -181,3 +179,21 @@ impl Drop for CanvasWrapper { let _ = self; } } + +impl From> for CanvasWrapper { + fn from(canvas: Canvas) -> Self { + Self(canvas) + } +} + +impl Borrow> for CanvasWrapper { + fn borrow(&self) -> &Canvas { + &self + } +} + +impl BorrowMut> for CanvasWrapper { + fn borrow_mut(&mut self) -> &mut Canvas { + self + } +} diff --git a/src/pipeline/predefined/grid_field_renderer.rs b/src/pipeline/predefined/grid_field_renderer.rs index 1d85059..0af1428 100644 --- a/src/pipeline/predefined/grid_field_renderer.rs +++ b/src/pipeline/predefined/grid_field_renderer.rs @@ -13,6 +13,7 @@ use image::{imageops::resize, ImageBuffer, Rgba}; use ndarray::ArrayView2; use num_traits::{AsPrimitive, FromPrimitive, Num, NumOps}; use std::{fmt::Debug, io::Cursor, marker::PhantomData}; +use gtk::ResponseType::No; #[derive(Debug)] pub struct GridFieldRenderer @@ -171,6 +172,7 @@ where let d2_start = data.dim2.view().first().unwrap().clone(); let d2_end = data.dim2.view().last().unwrap().clone(); + canvas.set_render_target(RenderTarget::Screen); Target::new( TargetType::Mem(png_data), @@ -178,6 +180,7 @@ where h, ((d1_start, d1_end).into(), (d2_start, d2_end).into()), Some(thumbnail_tex), + None ) } } diff --git a/src/widgets/render/imp.rs b/src/widgets/render/imp.rs index 044488d..807060b 100644 --- a/src/widgets/render/imp.rs +++ b/src/widgets/render/imp.rs @@ -9,6 +9,8 @@ use gtk::subclass::prelude::*; use gtk::traits::{GLAreaExt, WidgetExt}; use std::cell::{Cell, RefCell}; use std::num::NonZeroU32; +use std::rc::Rc; +use std::sync::{Arc, Mutex}; #[derive(Debug, Default, Clone, Copy, PartialEq)] pub struct RenderConfig { @@ -52,7 +54,7 @@ pub struct Render { pub config: RefCell, pub status: RefCell, pub mapper: RefCell, - pub(super) interior_layers: RefCell>, + pub(super) interior_layers: RefCell>>>, } impl Default for Render { @@ -61,7 +63,7 @@ impl Default for Render { render_status: Cell::new(0), exterior: RefCell::new(ExteriorWidget::default()), interior: RefCell::new(InteriorWidget::default()), - interior_layers: RefCell::new(Vec::new()), + interior_layers: RefCell::new(Rc::new(RefCell::new(Vec::new()))), config: RefCell::new(RenderConfig::default()), status: RefCell::new(RenderStatus::default()), mapper: RefCell::new(Mercator::default().into()), @@ -198,7 +200,8 @@ impl GLAreaImpl for Render { } } - let c = &(*self.interior_layers.borrow()); + let c = self.interior_layers.borrow(); + let c = &mut *c.borrow_mut(); self.interior .borrow() .draw(c, &self.obj(), self.status.borrow(), configs); diff --git a/src/widgets/render/interior/layers.rs b/src/widgets/render/interior/layers.rs index 4188a76..86e96cd 100644 --- a/src/widgets/render/interior/layers.rs +++ b/src/widgets/render/interior/layers.rs @@ -12,6 +12,7 @@ use std::{ pin::Pin, sync::{Arc, Mutex}, }; +use core_extensions::SelfOps; type PrepareFunc = Arc< Mutex< @@ -59,20 +60,14 @@ impl Layer { } } - pub fn draw(&self, render: &Render, window_size: (f32, f32)) { + pub fn draw(&mut self, render: &Render, window_size: (f32, f32)) { if self.visiable { - // if let Some(element) = &self.associated_element { - // let element = element.lock().unwrap(); - // match *element { - // Element::TimeSeries(ref e) => { - // if self.time.is_none() { - // return; - // } - // let time = self.time.unwrap(); - // } - // Element::Instant(ref e) => {} - // } - // } + match self.associated_element{ + AssoElement::Instant(ref mut e) => { + e.render(render); + } + AssoElement::TimeSeries(ref e) => {} + } } } diff --git a/src/widgets/render/interior/mod.rs b/src/widgets/render/interior/mod.rs index 506dee8..cde68d6 100644 --- a/src/widgets/render/interior/mod.rs +++ b/src/widgets/render/interior/mod.rs @@ -25,12 +25,12 @@ impl InteriorWidget { pub fn draw( &self, - layers: &Vec, + layers: &mut Vec, render: &Render, status: Ref<'_, RenderStatus>, _c: Ref<'_, RenderConfig>, ) { - for layer in layers.iter().filter(|x| x.visiable) { + for layer in layers.iter_mut().filter(|x| x.visiable) { layer.draw(render, (1000.0, 1000.0)); } } diff --git a/src/widgets/render/mod.rs b/src/widgets/render/mod.rs index c1633de..aa194a4 100644 --- a/src/widgets/render/mod.rs +++ b/src/widgets/render/mod.rs @@ -5,7 +5,8 @@ mod interior; pub mod predefined; pub mod renders; pub mod widget; -pub use self::cms::CMS; +// pub use self::cms::CMS; +use crate::coords::cms::CMS; pub use self::imp::{RenderConfig, RenderMotion, RenderStatus}; use crate::coords::Mapper; use adw::prelude::{GLAreaExt, GestureDragExt}; @@ -15,7 +16,9 @@ pub use glib::subclass::prelude::*; use gtk::traits::WidgetExt; use gtk::{EventControllerScrollFlags, Inhibit}; pub use interior::*; -use std::cell::{Ref, RefMut}; +use std::cell::{Ref, RefCell, RefMut}; +use std::rc::Rc; +use std::sync::{Arc, Mutex}; pub type WindowCoord = (f32, f32); @@ -124,7 +127,7 @@ impl Render { self.imp().mapper.replace(mapper); } - pub fn set_interior_layers(&self, layers: Vec) { + pub fn set_interior_layers(&self, layers: Rc>>) { self.imp().interior_layers.replace(layers); self.queue_render(); self.set_render_status(0); diff --git a/src/widgets/render/predefined/widgets.rs b/src/widgets/render/predefined/widgets.rs index 6b844c0..37f0ca4 100644 --- a/src/widgets/render/predefined/widgets.rs +++ b/src/widgets/render/predefined/widgets.rs @@ -3,7 +3,6 @@ use super::{ super::Layer, color_mapper::ColorMapper, }; -use crate::widgets::CMS; use femtovg::{renderer::OpenGl, Canvas, Color, Paint, Path}; use num_traits::*; #[derive(Debug)] diff --git a/src/widgets/render/widget/widget.rs b/src/widgets/render/widget/widget.rs index e800975..5c17c82 100644 --- a/src/widgets/render/widget/widget.rs +++ b/src/widgets/render/widget/widget.rs @@ -1,7 +1,8 @@ -use crate::widgets::{Layer, LayerImpl, Render, CMS}; +use crate::widgets::{Layer, LayerImpl, Render}; use femtovg::{renderer::OpenGl, Canvas}; use gtk::Align; use std::{fmt::Debug, rc::Rc}; +use crate::coords::cms::CMS; pub enum WidgetType { OpenGl,