mirror of
https://codeberg.org/waydeer/layer-shika.git
synced 2025-10-28 14:14:23 +00:00
92 lines
2.3 KiB
Rust
92 lines
2.3 KiB
Rust
use crate::errors::{LayerShikaError, Result};
|
|
use core::ops::Deref;
|
|
use log::info;
|
|
use slint::{
|
|
platform::{femtovg_renderer::FemtoVGRenderer, Renderer, WindowAdapter, WindowEvent},
|
|
PhysicalSize, Window, WindowSize,
|
|
};
|
|
use std::cell::Cell;
|
|
use std::rc::{Rc, Weak};
|
|
|
|
pub enum RenderState {
|
|
Clean,
|
|
Dirty,
|
|
}
|
|
|
|
pub struct FemtoVGWindow {
|
|
window: Window,
|
|
renderer: FemtoVGRenderer,
|
|
render_state: Cell<RenderState>,
|
|
size: Cell<PhysicalSize>,
|
|
scale_factor: Cell<f32>,
|
|
}
|
|
|
|
impl FemtoVGWindow {
|
|
pub fn new(renderer: FemtoVGRenderer) -> Rc<Self> {
|
|
Rc::new_cyclic(|weak_self| {
|
|
let window = Window::new(Weak::clone(weak_self) as Weak<dyn WindowAdapter>);
|
|
Self {
|
|
window,
|
|
renderer,
|
|
render_state: Cell::new(RenderState::Clean),
|
|
size: Cell::new(PhysicalSize::default()),
|
|
scale_factor: Cell::new(1.),
|
|
}
|
|
})
|
|
}
|
|
|
|
pub fn render_frame_if_dirty(&self) -> Result<()> {
|
|
if matches!(
|
|
self.render_state.replace(RenderState::Clean),
|
|
RenderState::Dirty
|
|
) {
|
|
self.renderer
|
|
.render()
|
|
.map_err(|e| LayerShikaError::Rendering(format!("Error rendering frame: {e}")))?;
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
pub fn set_scale_factor(&self, scale_factor: f32) {
|
|
info!("Setting scale factor to {scale_factor}");
|
|
self.scale_factor.set(scale_factor);
|
|
self.window()
|
|
.dispatch_event(WindowEvent::ScaleFactorChanged { scale_factor });
|
|
}
|
|
|
|
pub const fn scale_factor(&self) -> f32 {
|
|
self.scale_factor.get()
|
|
}
|
|
}
|
|
|
|
impl WindowAdapter for FemtoVGWindow {
|
|
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) {
|
|
self.size.set(size.to_physical(self.scale_factor()));
|
|
self.window.dispatch_event(WindowEvent::Resized {
|
|
size: size.to_logical(self.scale_factor()),
|
|
});
|
|
}
|
|
|
|
fn request_redraw(&self) {
|
|
self.render_state.set(RenderState::Dirty);
|
|
}
|
|
}
|
|
|
|
impl Deref for FemtoVGWindow {
|
|
type Target = Window;
|
|
fn deref(&self) -> &Self::Target {
|
|
&self.window
|
|
}
|
|
}
|