mirror of
https://codeberg.org/waydeer/layer-shika.git
synced 2025-11-17 23:14:23 +00:00
refactor: consolidate dimensions and scale
This commit is contained in:
parent
cc385fde3b
commit
af67a7ffb0
7 changed files with 127 additions and 108 deletions
|
|
@ -1,22 +1,29 @@
|
||||||
|
use layer_shika_domain::dimensions::{
|
||||||
|
LogicalSize as DomainLogicalSize, PhysicalSize as DomainPhysicalSize,
|
||||||
|
ScaleFactor as DomainScaleFactor,
|
||||||
|
};
|
||||||
|
use layer_shika_domain::surface_dimensions::SurfaceDimensions;
|
||||||
use log::info;
|
use log::info;
|
||||||
use slint::PhysicalSize;
|
use slint::PhysicalSize;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
pub struct DisplayMetrics {
|
pub struct DisplayMetrics {
|
||||||
scale_factor: f32,
|
surface: SurfaceDimensions,
|
||||||
output_size: PhysicalSize,
|
output_size: PhysicalSize,
|
||||||
surface_size: PhysicalSize,
|
|
||||||
has_fractional_scale: bool,
|
has_fractional_scale: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DisplayMetrics {
|
impl DisplayMetrics {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn new(scale_factor: f32, has_fractional_scale: bool) -> Self {
|
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 {
|
Self {
|
||||||
scale_factor,
|
surface,
|
||||||
output_size: PhysicalSize::new(0, 0),
|
output_size: PhysicalSize::new(0, 0),
|
||||||
surface_size: PhysicalSize::new(0, 0),
|
|
||||||
has_fractional_scale,
|
has_fractional_scale,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -24,12 +31,13 @@ impl DisplayMetrics {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn with_output_size(mut self, output_size: PhysicalSize) -> Self {
|
pub fn with_output_size(mut self, output_size: PhysicalSize) -> Self {
|
||||||
self.output_size = output_size;
|
self.output_size = output_size;
|
||||||
|
self.recalculate_surface_size();
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub const fn scale_factor(&self) -> f32 {
|
pub fn scale_factor(&self) -> f32 {
|
||||||
self.scale_factor
|
self.surface.scale_factor().value()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
|
|
@ -38,8 +46,11 @@ impl DisplayMetrics {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub const fn surface_size(&self) -> PhysicalSize {
|
pub fn surface_size(&self) -> PhysicalSize {
|
||||||
self.surface_size
|
PhysicalSize::new(
|
||||||
|
self.surface.physical_width(),
|
||||||
|
self.surface.physical_height(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
|
|
@ -49,15 +60,16 @@ impl DisplayMetrics {
|
||||||
|
|
||||||
#[allow(clippy::cast_precision_loss)]
|
#[allow(clippy::cast_precision_loss)]
|
||||||
pub fn update_scale_factor(&mut self, scale_120ths: u32) -> f32 {
|
pub fn update_scale_factor(&mut self, scale_120ths: u32) -> f32 {
|
||||||
let new_scale_factor = scale_120ths as f32 / 120.0;
|
let new_scale = DomainScaleFactor::from_120ths(scale_120ths);
|
||||||
let old_scale_factor = self.scale_factor;
|
let new_scale_factor = new_scale.value();
|
||||||
|
let old_scale_factor = self.scale_factor();
|
||||||
|
|
||||||
if (self.scale_factor - new_scale_factor).abs() > f32::EPSILON {
|
if (old_scale_factor - new_scale_factor).abs() > f32::EPSILON {
|
||||||
info!(
|
info!(
|
||||||
"DisplayMetrics: Updating scale factor from {} to {} ({}x)",
|
"DisplayMetrics: Updating scale factor from {} to {} ({}x)",
|
||||||
old_scale_factor, new_scale_factor, scale_120ths
|
old_scale_factor, new_scale_factor, scale_120ths
|
||||||
);
|
);
|
||||||
self.scale_factor = new_scale_factor;
|
self.surface.update_scale_factor(new_scale);
|
||||||
self.recalculate_surface_size();
|
self.recalculate_surface_size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -76,20 +88,15 @@ impl DisplayMetrics {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_surface_size(&mut self, surface_size: PhysicalSize) {
|
pub fn update_surface_size(&mut self, surface_size: PhysicalSize) {
|
||||||
self.surface_size = surface_size;
|
let physical = DomainPhysicalSize::from_raw(surface_size.width, surface_size.height);
|
||||||
|
self.surface = SurfaceDimensions::from_physical(physical, self.surface.scale_factor());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(
|
|
||||||
clippy::cast_possible_truncation,
|
|
||||||
clippy::cast_sign_loss,
|
|
||||||
clippy::cast_precision_loss
|
|
||||||
)]
|
|
||||||
fn recalculate_surface_size(&mut self) {
|
fn recalculate_surface_size(&mut self) {
|
||||||
if self.output_size.width > 0 && self.output_size.height > 0 && self.scale_factor > 0.0 {
|
if self.output_size.width > 0 && self.output_size.height > 0 && self.scale_factor() > 0.0 {
|
||||||
self.surface_size = PhysicalSize::new(
|
let physical =
|
||||||
(self.output_size.width as f32 / self.scale_factor) as u32,
|
DomainPhysicalSize::from_raw(self.output_size.width, self.output_size.height);
|
||||||
(self.output_size.height as f32 / self.scale_factor) as u32,
|
self.surface = SurfaceDimensions::from_physical(physical, self.surface.scale_factor());
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@ use crate::errors::{LayerShikaError, Result};
|
||||||
use crate::rendering::egl::context::EGLContext;
|
use crate::rendering::egl::context::EGLContext;
|
||||||
use crate::rendering::femtovg::{popup_window::PopupWindow, renderable_window::RenderableWindow};
|
use crate::rendering::femtovg::{popup_window::PopupWindow, renderable_window::RenderableWindow};
|
||||||
use crate::wayland::surfaces::display_metrics::SharedDisplayMetrics;
|
use crate::wayland::surfaces::display_metrics::SharedDisplayMetrics;
|
||||||
|
use layer_shika_domain::dimensions::{LogicalSize as DomainLogicalSize, ScaleFactor as DomainScaleFactor};
|
||||||
|
use layer_shika_domain::surface_dimensions::SurfaceDimensions;
|
||||||
use layer_shika_domain::value_objects::popup_config::PopupConfig;
|
use layer_shika_domain::value_objects::popup_config::PopupConfig;
|
||||||
use layer_shika_domain::value_objects::popup_positioning_mode::PopupPositioningMode;
|
use layer_shika_domain::value_objects::popup_positioning_mode::PopupPositioningMode;
|
||||||
use layer_shika_domain::value_objects::popup_request::{PopupHandle, PopupRequest};
|
use layer_shika_domain::value_objects::popup_request::{PopupHandle, PopupRequest};
|
||||||
|
|
@ -233,26 +235,26 @@ impl PopupManager {
|
||||||
|
|
||||||
let output_size = self.output_size();
|
let output_size = self.output_size();
|
||||||
#[allow(clippy::cast_precision_loss)]
|
#[allow(clippy::cast_precision_loss)]
|
||||||
let output_logical_size = (
|
let output_logical_size = DomainLogicalSize::from_raw(
|
||||||
output_size.width as f32 / scale_factor,
|
output_size.width as f32 / scale_factor,
|
||||||
output_size.height as f32 / scale_factor,
|
output_size.height as f32 / scale_factor,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let popup_logical_size = DomainLogicalSize::from_raw(params.width, params.height);
|
||||||
|
let domain_scale = DomainScaleFactor::from_raw(scale_factor);
|
||||||
|
let popup_dimensions = SurfaceDimensions::from_logical(popup_logical_size, domain_scale);
|
||||||
|
|
||||||
let popup_config = PopupConfig::new(
|
let popup_config = PopupConfig::new(
|
||||||
params.reference_x,
|
params.reference_x,
|
||||||
params.reference_y,
|
params.reference_y,
|
||||||
params.width,
|
popup_dimensions,
|
||||||
params.height,
|
|
||||||
params.positioning_mode,
|
params.positioning_mode,
|
||||||
output_logical_size.0,
|
output_logical_size,
|
||||||
output_logical_size.1,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
#[allow(clippy::cast_possible_truncation)]
|
|
||||||
#[allow(clippy::cast_sign_loss)]
|
|
||||||
let popup_size = PhysicalSize::new(
|
let popup_size = PhysicalSize::new(
|
||||||
(params.width * scale_factor) as u32,
|
popup_dimensions.physical_width(),
|
||||||
(params.height * scale_factor) as u32,
|
popup_dimensions.physical_height(),
|
||||||
);
|
);
|
||||||
|
|
||||||
info!("Popup physical size: {popup_size:?}");
|
info!("Popup physical size: {popup_size:?}");
|
||||||
|
|
@ -479,7 +481,8 @@ impl PopupManager {
|
||||||
|
|
||||||
if let Some(popup_key) = self.find_popup_key_by_fractional_scale_id(&fractional_scale_id) {
|
if let Some(popup_key) = self.find_popup_key_by_fractional_scale_id(&fractional_scale_id) {
|
||||||
if let Some(popup_window) = self.get_popup_window(popup_key) {
|
if let Some(popup_window) = self.get_popup_window(popup_key) {
|
||||||
let new_scale_factor = scale_120ths as f32 / 120.0;
|
let new_scale = DomainScaleFactor::from_120ths(scale_120ths);
|
||||||
|
let new_scale_factor = new_scale.value();
|
||||||
info!("Updating popup scale factor to {new_scale_factor} ({scale_120ths}x)");
|
info!("Updating popup scale factor to {new_scale_factor} ({scale_120ths}x)");
|
||||||
popup_window.set_scale_factor(new_scale_factor);
|
popup_window.set_scale_factor(new_scale_factor);
|
||||||
popup_window.request_redraw();
|
popup_window.request_redraw();
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,20 @@ impl LogicalSize {
|
||||||
pub fn as_tuple(&self) -> (f32, f32) {
|
pub fn as_tuple(&self) -> (f32, f32) {
|
||||||
(self.width, self.height)
|
(self.width, self.height)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn clamp_position(
|
||||||
|
&self,
|
||||||
|
position: LogicalPosition,
|
||||||
|
bounds: LogicalSize,
|
||||||
|
) -> LogicalPosition {
|
||||||
|
let max_x = (bounds.width - self.width).max(0.0);
|
||||||
|
let max_y = (bounds.height - self.height).max(0.0);
|
||||||
|
|
||||||
|
LogicalPosition::new(
|
||||||
|
position.x().max(0.0).min(max_x),
|
||||||
|
position.y().max(0.0).min(max_y),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for LogicalSize {
|
impl Default for LogicalSize {
|
||||||
|
|
@ -117,6 +131,11 @@ impl ScaleFactor {
|
||||||
Self(factor)
|
Self(factor)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::cast_precision_loss)]
|
||||||
|
pub fn from_120ths(scale_120ths: u32) -> Self {
|
||||||
|
Self(scale_120ths as f32 / 120.0)
|
||||||
|
}
|
||||||
|
|
||||||
pub const fn value(&self) -> f32 {
|
pub const fn value(&self) -> f32 {
|
||||||
self.0
|
self.0
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,11 +10,7 @@ pub struct SurfaceDimensions {
|
||||||
|
|
||||||
impl SurfaceDimensions {
|
impl SurfaceDimensions {
|
||||||
#[allow(clippy::cast_precision_loss)]
|
#[allow(clippy::cast_precision_loss)]
|
||||||
pub fn calculate(
|
pub fn calculate(logical_width: u32, logical_height: u32, scale_factor: f32) -> Result<Self> {
|
||||||
logical_width: u32,
|
|
||||||
logical_height: u32,
|
|
||||||
scale_factor: f32,
|
|
||||||
) -> Result<Self> {
|
|
||||||
let logical = LogicalSize::new(logical_width as f32, logical_height as f32)?;
|
let logical = LogicalSize::new(logical_width as f32, logical_height as f32)?;
|
||||||
let scale = ScaleFactor::new(scale_factor)?;
|
let scale = ScaleFactor::new(scale_factor)?;
|
||||||
let physical = scale.to_physical(logical);
|
let physical = scale.to_physical(logical);
|
||||||
|
|
@ -26,6 +22,36 @@ impl SurfaceDimensions {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn from_logical(logical: LogicalSize, scale_factor: ScaleFactor) -> Self {
|
||||||
|
let physical = scale_factor.to_physical(logical);
|
||||||
|
Self {
|
||||||
|
logical,
|
||||||
|
physical,
|
||||||
|
scale_factor,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_physical(physical: PhysicalSize, scale_factor: ScaleFactor) -> Self {
|
||||||
|
let logical = scale_factor.to_logical(physical);
|
||||||
|
Self {
|
||||||
|
logical,
|
||||||
|
physical,
|
||||||
|
scale_factor,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[must_use]
|
||||||
|
pub fn with_scale_factor(mut self, scale_factor: ScaleFactor) -> Self {
|
||||||
|
self.scale_factor = scale_factor;
|
||||||
|
self.physical = scale_factor.to_physical(self.logical);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_scale_factor(&mut self, scale_factor: ScaleFactor) {
|
||||||
|
self.scale_factor = scale_factor;
|
||||||
|
self.physical = scale_factor.to_physical(self.logical);
|
||||||
|
}
|
||||||
|
|
||||||
pub const fn logical_size(&self) -> LogicalSize {
|
pub const fn logical_size(&self) -> LogicalSize {
|
||||||
self.logical
|
self.logical
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,5 @@ pub mod keyboard_interactivity;
|
||||||
pub mod layer;
|
pub mod layer;
|
||||||
pub mod margins;
|
pub mod margins;
|
||||||
pub mod popup_config;
|
pub mod popup_config;
|
||||||
pub mod popup_dimensions;
|
|
||||||
pub mod popup_positioning_mode;
|
pub mod popup_positioning_mode;
|
||||||
pub mod popup_request;
|
pub mod popup_request;
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,12 @@
|
||||||
use super::popup_positioning_mode::PopupPositioningMode;
|
use super::popup_positioning_mode::PopupPositioningMode;
|
||||||
use crate::dimensions::{LogicalPosition, LogicalSize};
|
use crate::dimensions::{LogicalPosition, LogicalSize};
|
||||||
|
use crate::surface_dimensions::SurfaceDimensions;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct PopupConfig {
|
pub struct PopupConfig {
|
||||||
reference_position: LogicalPosition,
|
reference_position: LogicalPosition,
|
||||||
popup_size: LogicalSize,
|
dimensions: SurfaceDimensions,
|
||||||
output_size: LogicalSize,
|
output_bounds: LogicalSize,
|
||||||
positioning_mode: PopupPositioningMode,
|
positioning_mode: PopupPositioningMode,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -13,16 +14,14 @@ impl PopupConfig {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
reference_x: f32,
|
reference_x: f32,
|
||||||
reference_y: f32,
|
reference_y: f32,
|
||||||
width: f32,
|
dimensions: SurfaceDimensions,
|
||||||
height: f32,
|
|
||||||
positioning_mode: PopupPositioningMode,
|
positioning_mode: PopupPositioningMode,
|
||||||
output_width: f32,
|
output_bounds: LogicalSize,
|
||||||
output_height: f32,
|
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
reference_position: LogicalPosition::new(reference_x, reference_y),
|
reference_position: LogicalPosition::new(reference_x, reference_y),
|
||||||
popup_size: LogicalSize::from_raw(width, height),
|
dimensions,
|
||||||
output_size: LogicalSize::from_raw(output_width, output_height),
|
output_bounds,
|
||||||
positioning_mode,
|
positioning_mode,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -39,20 +38,24 @@ impl PopupConfig {
|
||||||
self.reference_position.y()
|
self.reference_position.y()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const fn popup_size(&self) -> LogicalSize {
|
pub const fn dimensions(&self) -> SurfaceDimensions {
|
||||||
self.popup_size
|
self.dimensions
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const fn width(&self) -> f32 {
|
pub fn popup_size(&self) -> LogicalSize {
|
||||||
self.popup_size.width()
|
self.dimensions.logical_size()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const fn height(&self) -> f32 {
|
pub fn width(&self) -> f32 {
|
||||||
self.popup_size.height()
|
self.dimensions.logical_size().width()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const fn output_size(&self) -> LogicalSize {
|
pub fn height(&self) -> f32 {
|
||||||
self.output_size
|
self.dimensions.logical_size().height()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn output_bounds(&self) -> LogicalSize {
|
||||||
|
self.output_bounds
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const fn positioning_mode(&self) -> PopupPositioningMode {
|
pub const fn positioning_mode(&self) -> PopupPositioningMode {
|
||||||
|
|
@ -60,28 +63,32 @@ impl PopupConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn calculated_top_left_position(&self) -> LogicalPosition {
|
pub fn calculated_top_left_position(&self) -> LogicalPosition {
|
||||||
LogicalPosition::new(self.calculated_top_left_x(), self.calculated_top_left_y())
|
let unclamped = self.calculate_unclamped_position();
|
||||||
|
self.popup_size()
|
||||||
|
.clamp_position(unclamped, self.output_bounds)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn calculated_top_left_x(&self) -> f32 {
|
fn calculate_unclamped_position(&self) -> LogicalPosition {
|
||||||
let unclamped_x = if self.positioning_mode.center_x() {
|
let x = if self.positioning_mode.center_x() {
|
||||||
self.reference_x() - (self.width() / 2.0)
|
self.reference_x() - (self.width() / 2.0)
|
||||||
} else {
|
} else {
|
||||||
self.reference_x()
|
self.reference_x()
|
||||||
};
|
};
|
||||||
|
|
||||||
let max_x = self.output_size.width() - self.width();
|
let y = if self.positioning_mode.center_y() {
|
||||||
unclamped_x.max(0.0).min(max_x)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn calculated_top_left_y(&self) -> f32 {
|
|
||||||
let unclamped_y = if self.positioning_mode.center_y() {
|
|
||||||
self.reference_y() - (self.height() / 2.0)
|
self.reference_y() - (self.height() / 2.0)
|
||||||
} else {
|
} else {
|
||||||
self.reference_y()
|
self.reference_y()
|
||||||
};
|
};
|
||||||
|
|
||||||
let max_y = self.output_size.height() - self.height();
|
LogicalPosition::new(x, y)
|
||||||
unclamped_y.max(0.0).min(max_y)
|
}
|
||||||
|
|
||||||
|
pub fn calculated_top_left_x(&self) -> f32 {
|
||||||
|
self.calculated_top_left_position().x()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn calculated_top_left_y(&self) -> f32 {
|
||||||
|
self.calculated_top_left_position().y()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,42 +0,0 @@
|
||||||
use crate::dimensions::LogicalSize;
|
|
||||||
use crate::errors::{DomainError, Result};
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Default)]
|
|
||||||
pub struct PopupDimensions {
|
|
||||||
size: LogicalSize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PopupDimensions {
|
|
||||||
pub fn new(width: f32, height: f32) -> Result<Self> {
|
|
||||||
let size = LogicalSize::new(width, height)?;
|
|
||||||
Ok(Self { size })
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const fn from_logical(size: LogicalSize) -> Self {
|
|
||||||
Self { size }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const fn width(&self) -> f32 {
|
|
||||||
self.size.width()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const fn height(&self) -> f32 {
|
|
||||||
self.size.height()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const fn logical_size(&self) -> LogicalSize {
|
|
||||||
self.size
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn as_tuple(&self) -> (f32, f32) {
|
|
||||||
self.size.as_tuple()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TryFrom<(f32, f32)> for PopupDimensions {
|
|
||||||
type Error = DomainError;
|
|
||||||
|
|
||||||
fn try_from((width, height): (f32, f32)) -> Result<Self> {
|
|
||||||
Self::new(width, height)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Add table
Reference in a new issue