layer_shika_composition/popup/
mod.rs

1use crate::popup_builder::{Bound, PopupBuilder};
2use crate::system::{PopupCommand, ShellCommand, ShellControl};
3use crate::{Error, Result};
4use layer_shika_adapters::platform::calloop::channel;
5use layer_shika_domain::errors::DomainError;
6use layer_shika_domain::value_objects::handle::PopupHandle;
7use layer_shika_domain::value_objects::popup_config::PopupConfig;
8
9#[derive(Clone)]
10pub struct PopupShell {
11    sender: channel::Sender<ShellCommand>,
12}
13
14impl PopupShell {
15    #[must_use]
16    pub const fn new(sender: channel::Sender<ShellCommand>) -> Self {
17        Self { sender }
18    }
19
20    /// Creates a popup builder bound to this shell
21    ///
22    /// The returned builder can call `.show()` directly because it's bound to a shell.
23    #[must_use]
24    pub fn builder(&self, component: impl Into<String>) -> PopupBuilder<Bound> {
25        PopupBuilder::new(component).with_shell(self.clone())
26    }
27
28    pub fn show(&self, config: PopupConfig) -> Result<PopupHandle> {
29        let handle = PopupHandle::new();
30        self.sender
31            .send(ShellCommand::Popup(PopupCommand::Show { handle, config }))
32            .map_err(|_| Error::Domain(DomainError::ChannelClosed))?;
33        Ok(handle)
34    }
35
36    pub fn close(&self, handle: PopupHandle) -> Result<()> {
37        ShellControl::new(self.sender.clone()).close_popup(handle)
38    }
39
40    pub fn resize_fixed(&self, handle: PopupHandle, width: f32, height: f32) -> Result<()> {
41        ShellControl::new(self.sender.clone()).resize_popup(handle, width, height)
42    }
43}