refactor: type-state builder pattern for windowing system

This commit is contained in:
drendog 2025-10-25 19:15:23 +02:00
parent 55e85a1e95
commit 98c506dfd2
Signed by: dwenya
GPG key ID: 8DD77074645332D0

View file

@ -1,67 +1,61 @@
use super::{
config::{Margins, WindowConfig},
WindowingSystem,
};
use crate::errors::Result;
use slint_interpreter::ComponentDefinition; use slint_interpreter::ComponentDefinition;
use smithay_client_toolkit::reexports::protocols_wlr::layer_shell::v1::client::{ use smithay_client_toolkit::reexports::protocols_wlr::layer_shell::v1::client::{
zwlr_layer_shell_v1::{self}, zwlr_layer_shell_v1::{self},
zwlr_layer_surface_v1::{Anchor, KeyboardInteractivity}, zwlr_layer_surface_v1::{Anchor, KeyboardInteractivity},
}; };
use std::marker::PhantomData;
use crate::errors::{LayerShikaError, Result}; pub struct NeedsComponent;
pub struct HasComponent;
use super::{ pub struct WindowingSystemBuilder<State = NeedsComponent> {
config::{Margins, WindowConfig}, config: WindowConfig,
WindowingSystem, _state: PhantomData<State>,
};
pub struct WindowingSystemBuilder {
config: Option<WindowConfig>,
} }
impl Default for WindowingSystemBuilder { impl WindowingSystemBuilder<NeedsComponent> {
fn default() -> Self {
Self::new()
}
}
impl WindowingSystemBuilder {
#[inline] #[inline]
#[must_use] #[must_use]
pub const fn new() -> Self { pub fn new(component_definition: ComponentDefinition) -> WindowingSystemBuilder<HasComponent> {
Self { config: None } WindowingSystemBuilder {
config: WindowConfig::new(component_definition),
_state: PhantomData,
}
} }
}
impl WindowingSystemBuilder<HasComponent> {
#[must_use] #[must_use]
pub const fn with_height(mut self, height: u32) -> Self { pub const fn with_height(mut self, height: u32) -> Self {
if let Some(ref mut config) = self.config { self.config.height = height;
config.height = height;
}
self self
} }
#[must_use] #[must_use]
pub const fn with_layer(mut self, layer: zwlr_layer_shell_v1::Layer) -> Self { pub const fn with_layer(mut self, layer: zwlr_layer_shell_v1::Layer) -> Self {
if let Some(ref mut config) = self.config { self.config.layer = layer;
config.layer = layer;
}
self self
} }
#[must_use] #[must_use]
pub const fn with_margin(mut self, top: i32, right: i32, bottom: i32, left: i32) -> Self { pub const fn with_margin(mut self, top: i32, right: i32, bottom: i32, left: i32) -> Self {
if let Some(ref mut config) = self.config { self.config.margin = Margins {
config.margin = Margins { top,
top, right,
right, bottom,
bottom, left,
left, };
};
}
self self
} }
#[must_use] #[must_use]
pub const fn with_anchor(mut self, anchor: Anchor) -> Self { pub const fn with_anchor(mut self, anchor: Anchor) -> Self {
if let Some(ref mut config) = self.config { self.config.anchor = anchor;
config.anchor = anchor;
}
self self
} }
@ -70,47 +64,30 @@ impl WindowingSystemBuilder {
mut self, mut self,
interactivity: KeyboardInteractivity, interactivity: KeyboardInteractivity,
) -> Self { ) -> Self {
if let Some(ref mut config) = self.config { self.config.keyboard_interactivity = interactivity;
config.keyboard_interactivity = interactivity;
}
self self
} }
#[must_use] #[must_use]
pub const fn with_exclusive_zone(mut self, zone: i32) -> Self { pub const fn with_exclusive_zone(mut self, zone: i32) -> Self {
if let Some(ref mut config) = self.config { self.config.exclusive_zone = zone;
config.exclusive_zone = zone;
}
self self
} }
#[must_use] #[must_use]
pub fn with_namespace(mut self, namespace: String) -> Self { pub fn with_namespace(mut self, namespace: String) -> Self {
if let Some(ref mut config) = self.config { self.config.namespace = namespace;
config.namespace = namespace;
}
self self
} }
#[must_use] #[must_use]
pub const fn with_scale_factor(mut self, scale_factor: f32) -> Self { pub const fn with_scale_factor(mut self, scale_factor: f32) -> Self {
if let Some(ref mut config) = self.config { self.config.scale_factor = scale_factor;
config.scale_factor = scale_factor;
}
self
}
#[must_use]
pub fn with_component_definition(mut self, component: ComponentDefinition) -> Self {
self.config = Some(WindowConfig::new(component));
self self
} }
#[allow(clippy::missing_errors_doc)] #[allow(clippy::missing_errors_doc)]
pub fn build(self) -> Result<WindowingSystem> { pub fn build(self) -> Result<WindowingSystem> {
let config = self WindowingSystem::new(self.config)
.config
.ok_or_else(|| LayerShikaError::InvalidInput("Slint component not set".into()))?;
WindowingSystem::new(config)
} }
} }