use core::{ cell::Cell, ops::{Deref, DerefMut}, }; use alloc::rc::{Rc, Weak}; use slint::{ PhysicalSize, Window, WindowSize, platform::{Renderer, WindowAdapter, WindowEvent, software_renderer::SoftwareRenderer}, }; /// This is a minimal adapter for a Window that doesn't have any other feature than rendering /// using the software renderer. pub struct SoftwareWindowAdapter { pub window: Window, pub renderer: SoftwareRenderer, needs_redraw: Cell, size: Cell, } impl SoftwareWindowAdapter { /// Instantiate a new MinimalWindowAdaptor /// /// The `repaint_buffer_type` parameter specify what kind of buffer are passed to the [`SoftwareRenderer`] pub fn new(renderer: SoftwareRenderer) -> Rc { Rc::new_cyclic(|w: &Weak| Self { window: Window::new(w.clone()), renderer, needs_redraw: Cell::new(true), size: Default::default(), }) } /// If the window needs to be redrawn, the callback will be called with the /// [renderer](SoftwareRenderer) that should be used to do the drawing. /// /// [`SoftwareRenderer::render()`] or [`SoftwareRenderer::render_by_line()`] should be called /// in that callback. /// /// Return true if something was redrawn. pub fn draw_if_needed(&self, render_callback: impl FnOnce(&SoftwareRenderer)) -> bool { if self.needs_redraw.replace(false) /*|| self.renderer.rendering_metrics_collector.is_some()*/ { render_callback(&self.renderer); true } else { false } } // pub fn set_scale_factor(&self, scale_factor: f32) { // self.window.dispatch_event(WindowEvent::ScaleFactorChanged { scale_factor }); // } } impl WindowAdapter for SoftwareWindowAdapter { fn window(&self) -> &Window { &self.window } fn renderer(&self) -> &dyn Renderer { &self.renderer } fn size(&self) -> PhysicalSize { self.size.get() } fn set_size(&self, size: WindowSize) { let sf = self.window.scale_factor(); self.size.set(size.to_physical(sf)); self.window.dispatch_event(WindowEvent::Resized { size: size.to_logical(sf), }) } fn request_redraw(&self) { self.needs_redraw.set(true); } } impl Deref for SoftwareWindowAdapter { type Target = Window; fn deref(&self) -> &Self::Target { &self.window } } impl DerefMut for SoftwareWindowAdapter { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.window } }