mirror of
https://codeberg.org/waydeer/layer-shika.git
synced 2026-01-22 09:15:55 +00:00
127 lines
3.9 KiB
Rust
127 lines
3.9 KiB
Rust
use layer_shika_domain::dimensions::{
|
|
LogicalSize as DomainLogicalSize, PhysicalSize as DomainPhysicalSize,
|
|
ScaleFactor as DomainScaleFactor,
|
|
};
|
|
use layer_shika_domain::errors::Result as DomainResult;
|
|
use layer_shika_domain::surface_dimensions::SurfaceDimensions;
|
|
use log::info;
|
|
use slint::PhysicalSize;
|
|
use std::cell::RefCell;
|
|
use std::rc::Rc;
|
|
|
|
pub struct DisplayMetrics {
|
|
surface: SurfaceDimensions,
|
|
output_size: PhysicalSize,
|
|
has_fractional_scale: bool,
|
|
}
|
|
|
|
impl DisplayMetrics {
|
|
#[must_use]
|
|
pub fn new(scale_factor: f32, has_fractional_scale: bool) -> Self {
|
|
let scale = DomainScaleFactor::from_raw(scale_factor);
|
|
let logical = DomainLogicalSize::from_raw(1.0, 1.0);
|
|
let surface = SurfaceDimensions::from_logical(logical, scale);
|
|
|
|
Self {
|
|
surface,
|
|
output_size: PhysicalSize::new(0, 0),
|
|
has_fractional_scale,
|
|
}
|
|
}
|
|
|
|
#[must_use]
|
|
pub fn with_output_size(mut self, output_size: PhysicalSize) -> Self {
|
|
self.output_size = output_size;
|
|
self.recalculate_surface_size();
|
|
self
|
|
}
|
|
|
|
#[must_use]
|
|
pub fn scale_factor(&self) -> f32 {
|
|
self.surface.scale_factor().value()
|
|
}
|
|
|
|
#[must_use]
|
|
pub fn scale_factor_typed(&self) -> DomainScaleFactor {
|
|
self.surface.scale_factor()
|
|
}
|
|
|
|
#[must_use]
|
|
pub const fn output_size(&self) -> PhysicalSize {
|
|
self.output_size
|
|
}
|
|
|
|
#[must_use]
|
|
pub fn surface_size(&self) -> PhysicalSize {
|
|
PhysicalSize::new(
|
|
self.surface.physical_width(),
|
|
self.surface.physical_height(),
|
|
)
|
|
}
|
|
|
|
#[must_use]
|
|
pub const fn surface_dimensions(&self) -> &SurfaceDimensions {
|
|
&self.surface
|
|
}
|
|
|
|
#[must_use]
|
|
pub const fn has_fractional_scale(&self) -> bool {
|
|
self.has_fractional_scale
|
|
}
|
|
|
|
pub fn calculate_dimensions(
|
|
&self,
|
|
logical_width: u32,
|
|
logical_height: u32,
|
|
) -> DomainResult<SurfaceDimensions> {
|
|
SurfaceDimensions::calculate(logical_width, logical_height, self.scale_factor())
|
|
}
|
|
|
|
pub fn scale_factor_from_120ths(scale_120ths: u32) -> f32 {
|
|
DomainScaleFactor::from_120ths(scale_120ths).value()
|
|
}
|
|
|
|
#[allow(clippy::cast_precision_loss)]
|
|
pub fn update_scale_factor(&mut self, scale_120ths: u32) -> f32 {
|
|
let new_scale = DomainScaleFactor::from_120ths(scale_120ths);
|
|
let new_scale_factor = new_scale.value();
|
|
let old_scale_factor = self.scale_factor();
|
|
|
|
if (old_scale_factor - new_scale_factor).abs() > f32::EPSILON {
|
|
info!(
|
|
"DisplayMetrics: Updating scale factor from {} to {} ({}x)",
|
|
old_scale_factor, new_scale_factor, scale_120ths
|
|
);
|
|
self.surface.update_scale_factor(new_scale);
|
|
self.recalculate_surface_size();
|
|
}
|
|
|
|
new_scale_factor
|
|
}
|
|
|
|
pub fn update_output_size(&mut self, output_size: PhysicalSize) {
|
|
if self.output_size != output_size {
|
|
info!(
|
|
"DisplayMetrics: Updating output size from {:?} to {:?}",
|
|
self.output_size, output_size
|
|
);
|
|
self.output_size = output_size;
|
|
self.recalculate_surface_size();
|
|
}
|
|
}
|
|
|
|
pub fn update_surface_size(&mut self, surface_size: PhysicalSize) {
|
|
let physical = DomainPhysicalSize::from_raw(surface_size.width, surface_size.height);
|
|
self.surface = SurfaceDimensions::from_physical(physical, self.surface.scale_factor());
|
|
}
|
|
|
|
fn recalculate_surface_size(&mut self) {
|
|
if self.output_size.width > 0 && self.output_size.height > 0 && self.scale_factor() > 0.0 {
|
|
let physical =
|
|
DomainPhysicalSize::from_raw(self.output_size.width, self.output_size.height);
|
|
self.surface = SurfaceDimensions::from_physical(physical, self.surface.scale_factor());
|
|
}
|
|
}
|
|
}
|
|
|
|
pub type SharedDisplayMetrics = Rc<RefCell<DisplayMetrics>>;
|