mirror of
https://codeberg.org/waydeer/layer-shika.git
synced 2025-12-12 13:25:54 +00:00
feat: add declarative config support
This commit is contained in:
parent
983056abfc
commit
aa536c9487
9 changed files with 261 additions and 18 deletions
|
|
@ -4,6 +4,7 @@ mod event_loop;
|
|||
mod layer_surface;
|
||||
mod popup_builder;
|
||||
mod shell;
|
||||
mod shell_config;
|
||||
mod shell_runtime;
|
||||
mod system;
|
||||
pub mod value_conversion;
|
||||
|
|
@ -38,6 +39,8 @@ pub use shell::{
|
|||
SurfaceConfigBuilder, SurfaceDefinition,
|
||||
};
|
||||
|
||||
pub use shell_config::{CompiledUiSource, ShellConfig, SurfaceComponentConfig};
|
||||
|
||||
pub mod calloop {
|
||||
pub use layer_shika_adapters::platform::calloop::{
|
||||
Generic, Interest, Mode, PostAction, RegistrationToken, TimeoutAction, Timer, channel,
|
||||
|
|
@ -60,12 +63,13 @@ pub enum Error {
|
|||
|
||||
pub mod prelude {
|
||||
pub use crate::{
|
||||
AnchorEdges, AnchorStrategy, DEFAULT_COMPONENT_NAME, DEFAULT_SURFACE_NAME, EventContext,
|
||||
EventLoopHandle, IntoValue, KeyboardInteractivity, Layer, LayerSurfaceHandle,
|
||||
OutputGeometry, OutputHandle, OutputInfo, OutputPolicy, OutputRegistry, PopupBuilder,
|
||||
PopupHandle, PopupPlacement, PopupPositioningMode, PopupRequest, PopupSize, PopupWindow,
|
||||
Result, Shell, ShellBuilder, ShellControl, ShellEventContext, ShellEventLoopHandle,
|
||||
ShellRuntime, ShellSurfaceConfigHandler, ShellSurfaceHandle, SingleWindowShell,
|
||||
AnchorEdges, AnchorStrategy, CompiledUiSource, DEFAULT_COMPONENT_NAME,
|
||||
DEFAULT_SURFACE_NAME, EventContext, EventLoopHandle, IntoValue, KeyboardInteractivity,
|
||||
Layer, LayerSurfaceHandle, OutputGeometry, OutputHandle, OutputInfo, OutputPolicy,
|
||||
OutputRegistry, PopupBuilder, PopupHandle, PopupPlacement, PopupPositioningMode,
|
||||
PopupRequest, PopupSize, PopupWindow, Result, Shell, ShellBuilder, ShellConfig,
|
||||
ShellControl, ShellEventContext, ShellEventLoopHandle, ShellRuntime,
|
||||
ShellSurfaceConfigHandler, ShellSurfaceHandle, SingleWindowShell, SurfaceComponentConfig,
|
||||
SurfaceConfigBuilder, SurfaceDefinition,
|
||||
};
|
||||
|
||||
|
|
@ -74,7 +78,7 @@ pub mod prelude {
|
|||
pub use crate::{slint, slint_interpreter};
|
||||
|
||||
pub use layer_shika_domain::prelude::{
|
||||
LogicalSize, Margins, PhysicalSize, ScaleFactor, SurfaceConfig, SurfaceDimension,
|
||||
LogicalSize, Margins, PhysicalSize, ScaleFactor, SurfaceConfig, SurfaceDimension, UiSource,
|
||||
};
|
||||
|
||||
pub use layer_shika_adapters::platform::wayland::Anchor;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use crate::event_loop::{EventLoopHandleBase, FromAppState};
|
||||
use crate::layer_surface::LayerSurfaceHandle;
|
||||
use crate::popup_builder::PopupBuilder;
|
||||
use crate::shell_config::{CompiledUiSource, ShellConfig};
|
||||
use crate::shell_runtime::ShellRuntime;
|
||||
use crate::system::{PopupCommand, ShellControl};
|
||||
use crate::value_conversion::IntoValue;
|
||||
|
|
@ -314,6 +315,32 @@ impl Shell {
|
|||
Ok(Rc::new(result))
|
||||
}
|
||||
|
||||
pub fn from_config(config: ShellConfig) -> Result<Self> {
|
||||
let compilation_result = match config.ui_source {
|
||||
CompiledUiSource::File(path) => Self::compile_file(&path)?,
|
||||
CompiledUiSource::Source(code) => Self::compile_source(code)?,
|
||||
CompiledUiSource::Compiled(result) => result,
|
||||
};
|
||||
|
||||
let surfaces: Vec<SurfaceDefinition> = if config.surfaces.is_empty() {
|
||||
vec![SurfaceDefinition {
|
||||
component: DEFAULT_COMPONENT_NAME.to_string(),
|
||||
config: SurfaceConfig::default(),
|
||||
}]
|
||||
} else {
|
||||
config
|
||||
.surfaces
|
||||
.into_iter()
|
||||
.map(|s| SurfaceDefinition {
|
||||
component: s.component,
|
||||
config: s.config,
|
||||
})
|
||||
.collect()
|
||||
};
|
||||
|
||||
Self::new(compilation_result, surfaces)
|
||||
}
|
||||
|
||||
pub(crate) fn new(
|
||||
compilation_result: Rc<CompilationResult>,
|
||||
definitions: Vec<SurfaceDefinition>,
|
||||
|
|
|
|||
148
crates/composition/src/shell_config.rs
Normal file
148
crates/composition/src/shell_config.rs
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
use layer_shika_adapters::platform::slint_interpreter::CompilationResult;
|
||||
use layer_shika_domain::prelude::{SurfaceConfig, UiSource};
|
||||
use std::path::PathBuf;
|
||||
use std::rc::Rc;
|
||||
|
||||
pub enum CompiledUiSource {
|
||||
File(PathBuf),
|
||||
Source(String),
|
||||
Compiled(Rc<CompilationResult>),
|
||||
}
|
||||
|
||||
impl CompiledUiSource {
|
||||
pub fn file(path: impl Into<PathBuf>) -> Self {
|
||||
Self::File(path.into())
|
||||
}
|
||||
|
||||
pub fn source(code: impl Into<String>) -> Self {
|
||||
Self::Source(code.into())
|
||||
}
|
||||
|
||||
pub fn compiled(result: Rc<CompilationResult>) -> Self {
|
||||
Self::Compiled(result)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<UiSource> for CompiledUiSource {
|
||||
fn from(source: UiSource) -> Self {
|
||||
match source {
|
||||
UiSource::File(path) => Self::File(path),
|
||||
UiSource::Source(code) => Self::Source(code),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Rc<CompilationResult>> for CompiledUiSource {
|
||||
fn from(result: Rc<CompilationResult>) -> Self {
|
||||
Self::Compiled(result)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&str> for CompiledUiSource {
|
||||
fn from(s: &str) -> Self {
|
||||
Self::File(PathBuf::from(s))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for CompiledUiSource {
|
||||
fn from(s: String) -> Self {
|
||||
Self::File(PathBuf::from(s))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<PathBuf> for CompiledUiSource {
|
||||
fn from(path: PathBuf) -> Self {
|
||||
Self::File(path)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ShellConfig {
|
||||
pub ui_source: CompiledUiSource,
|
||||
pub surfaces: Vec<SurfaceComponentConfig>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct SurfaceComponentConfig {
|
||||
pub component: String,
|
||||
pub config: SurfaceConfig,
|
||||
}
|
||||
|
||||
impl ShellConfig {
|
||||
pub fn new(ui_source: impl Into<CompiledUiSource>) -> Self {
|
||||
Self {
|
||||
ui_source: ui_source.into(),
|
||||
surfaces: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn with_surface(mut self, component: impl Into<String>) -> Self {
|
||||
self.surfaces.push(SurfaceComponentConfig {
|
||||
component: component.into(),
|
||||
config: SurfaceConfig::default(),
|
||||
});
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn with_surface_config(
|
||||
mut self,
|
||||
component: impl Into<String>,
|
||||
config: SurfaceConfig,
|
||||
) -> Self {
|
||||
self.surfaces.push(SurfaceComponentConfig {
|
||||
component: component.into(),
|
||||
config,
|
||||
});
|
||||
self
|
||||
}
|
||||
|
||||
pub fn add_surface(&mut self, component: impl Into<String>) -> &mut SurfaceComponentConfig {
|
||||
self.surfaces.push(SurfaceComponentConfig {
|
||||
component: component.into(),
|
||||
config: SurfaceConfig::default(),
|
||||
});
|
||||
self.surfaces
|
||||
.last_mut()
|
||||
.unwrap_or_else(|| unreachable!("just pushed"))
|
||||
}
|
||||
|
||||
pub fn add_surface_config(
|
||||
&mut self,
|
||||
component: impl Into<String>,
|
||||
config: SurfaceConfig,
|
||||
) -> &mut SurfaceComponentConfig {
|
||||
self.surfaces.push(SurfaceComponentConfig {
|
||||
component: component.into(),
|
||||
config,
|
||||
});
|
||||
self.surfaces
|
||||
.last_mut()
|
||||
.unwrap_or_else(|| unreachable!("just pushed"))
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for ShellConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
ui_source: CompiledUiSource::Source(String::new()),
|
||||
surfaces: Vec::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl SurfaceComponentConfig {
|
||||
pub fn new(component: impl Into<String>) -> Self {
|
||||
Self {
|
||||
component: component.into(),
|
||||
config: SurfaceConfig::default(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_config(component: impl Into<String>, config: SurfaceConfig) -> Self {
|
||||
Self {
|
||||
component: component.into(),
|
||||
config,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -16,3 +16,4 @@ pub use crate::value_objects::margins::Margins;
|
|||
pub use crate::value_objects::output_handle::OutputHandle;
|
||||
pub use crate::value_objects::output_info::{OutputGeometry, OutputInfo};
|
||||
pub use crate::value_objects::output_policy::OutputPolicy;
|
||||
pub use crate::value_objects::ui_source::UiSource;
|
||||
|
|
|
|||
|
|
@ -10,3 +10,4 @@ pub mod output_policy;
|
|||
pub mod popup_config;
|
||||
pub mod popup_positioning_mode;
|
||||
pub mod popup_request;
|
||||
pub mod ui_source;
|
||||
|
|
|
|||
35
crates/domain/src/value_objects/ui_source.rs
Normal file
35
crates/domain/src/value_objects/ui_source.rs
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
use std::path::PathBuf;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum UiSource {
|
||||
File(PathBuf),
|
||||
Source(String),
|
||||
}
|
||||
|
||||
impl UiSource {
|
||||
pub fn file(path: impl Into<PathBuf>) -> Self {
|
||||
Self::File(path.into())
|
||||
}
|
||||
|
||||
pub fn source(code: impl Into<String>) -> Self {
|
||||
Self::Source(code.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&str> for UiSource {
|
||||
fn from(s: &str) -> Self {
|
||||
Self::File(PathBuf::from(s))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for UiSource {
|
||||
fn from(s: String) -> Self {
|
||||
Self::File(PathBuf::from(s))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<PathBuf> for UiSource {
|
||||
fn from(path: PathBuf) -> Self {
|
||||
Self::File(path)
|
||||
}
|
||||
}
|
||||
34
src/lib.rs
34
src/lib.rs
|
|
@ -28,9 +28,9 @@
|
|||
//! - [`slint_integration`] – Slint framework re-exports and wrappers
|
||||
//! - [`calloop`] – Event loop types for custom event sources
|
||||
//!
|
||||
//! # Quick Start
|
||||
//! # Quick Start (Fluent Builder)
|
||||
//!
|
||||
//! Single-surface use case:
|
||||
//! Single-surface use case with the fluent builder API:
|
||||
//!
|
||||
//! ```rust,no_run
|
||||
//! use layer_shika::prelude::*;
|
||||
|
|
@ -45,6 +45,29 @@
|
|||
//! # Ok::<(), layer_shika::Error>(())
|
||||
//! ```
|
||||
//!
|
||||
//! # Declarative Configuration
|
||||
//!
|
||||
//! For reusable, programmatically generated, or externally sourced configurations:
|
||||
//!
|
||||
//! ```rust,no_run
|
||||
//! use layer_shika::prelude::*;
|
||||
//!
|
||||
//! let config = ShellConfig {
|
||||
//! ui_source: UiSource::file("ui/bar.slint"),
|
||||
//! surfaces: vec![
|
||||
//! SurfaceComponentConfig::with_config("Bar", SurfaceConfig {
|
||||
//! dimensions: SurfaceDimension::new(0, 42),
|
||||
//! anchor: AnchorEdges::top_bar(),
|
||||
//! exclusive_zone: 42,
|
||||
//! ..Default::default()
|
||||
//! }),
|
||||
//! ],
|
||||
//! };
|
||||
//!
|
||||
//! Shell::from_config(config)?.run()?;
|
||||
//! # Ok::<(), layer_shika::Error>(())
|
||||
//! ```
|
||||
//!
|
||||
//! # Multi-Surface Shell
|
||||
//!
|
||||
//! Same API naturally extends to multiple surfaces:
|
||||
|
|
@ -98,9 +121,10 @@ pub mod window;
|
|||
pub use layer_shika_composition::{Error, Result};
|
||||
|
||||
pub use shell::{
|
||||
DEFAULT_COMPONENT_NAME, DEFAULT_SURFACE_NAME, LayerSurfaceHandle, Shell, ShellBuilder,
|
||||
ShellControl, ShellEventContext, ShellEventLoopHandle, ShellRuntime, ShellSurfaceConfigHandler,
|
||||
ShellSurfaceHandle, SingleWindowShell, SurfaceConfigBuilder, SurfaceDefinition,
|
||||
CompiledUiSource, DEFAULT_COMPONENT_NAME, DEFAULT_SURFACE_NAME, LayerSurfaceHandle, Shell,
|
||||
ShellBuilder, ShellConfig, ShellControl, ShellEventContext, ShellEventLoopHandle, ShellRuntime,
|
||||
ShellSurfaceConfigHandler, ShellSurfaceHandle, SingleWindowShell, SurfaceComponentConfig,
|
||||
SurfaceConfigBuilder, SurfaceDefinition,
|
||||
};
|
||||
|
||||
pub use window::{
|
||||
|
|
|
|||
|
|
@ -9,9 +9,10 @@
|
|||
#![allow(clippy::pub_use)]
|
||||
|
||||
pub use crate::shell::{
|
||||
DEFAULT_COMPONENT_NAME, DEFAULT_SURFACE_NAME, LayerSurfaceHandle, Shell, ShellBuilder,
|
||||
ShellControl, ShellEventContext, ShellEventLoopHandle, ShellRuntime, ShellSurfaceConfigHandler,
|
||||
ShellSurfaceHandle, SingleWindowShell, SurfaceConfigBuilder, SurfaceDefinition,
|
||||
CompiledUiSource, DEFAULT_COMPONENT_NAME, DEFAULT_SURFACE_NAME, LayerSurfaceHandle, Shell,
|
||||
ShellBuilder, ShellConfig, ShellControl, ShellEventContext, ShellEventLoopHandle, ShellRuntime,
|
||||
ShellSurfaceConfigHandler, ShellSurfaceHandle, SingleWindowShell, SurfaceComponentConfig,
|
||||
SurfaceConfigBuilder, SurfaceDefinition,
|
||||
};
|
||||
|
||||
pub use crate::window::{
|
||||
|
|
@ -29,6 +30,7 @@ pub use crate::{Error, Result};
|
|||
|
||||
pub use layer_shika_composition::prelude::{
|
||||
Anchor, LogicalSize, Margins, PhysicalSize, ScaleFactor, SurfaceConfig, SurfaceDimension,
|
||||
UiSource,
|
||||
};
|
||||
|
||||
pub use crate::calloop;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
pub use layer_shika_composition::{
|
||||
DEFAULT_COMPONENT_NAME, DEFAULT_SURFACE_NAME, LayerSurfaceHandle, Shell, ShellBuilder,
|
||||
ShellControl, ShellEventContext, ShellEventLoopHandle, ShellRuntime, ShellSurfaceConfigHandler,
|
||||
ShellSurfaceHandle, SingleWindowShell, SurfaceConfigBuilder, SurfaceDefinition,
|
||||
CompiledUiSource, DEFAULT_COMPONENT_NAME, DEFAULT_SURFACE_NAME, LayerSurfaceHandle, Shell,
|
||||
ShellBuilder, ShellConfig, ShellControl, ShellEventContext, ShellEventLoopHandle, ShellRuntime,
|
||||
ShellSurfaceConfigHandler, ShellSurfaceHandle, SingleWindowShell, SurfaceComponentConfig,
|
||||
SurfaceConfigBuilder, SurfaceDefinition,
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue