use super::FloatingWindow;
use super::config::{Position, Size, WindowConfig, WindowLevel};
use crate::gui::animation::WindowAnimation;
use crate::gui::content::Content;
use crate::gui::effect::{PresetEffect, PresetEffectOptions};
use crate::gui::event::FloatingWindowEvent;
use crate::gui::icon::WindowIcon;
use crate::gui::shape::WindowShape;
#[allow(clippy::type_complexity)]
pub struct FloatingWindowBuilder {
config: WindowConfig,
event_callback: Option<Box<dyn Fn(&FloatingWindowEvent) + Send + Sync>>,
}
impl Default for FloatingWindowBuilder {
fn default() -> Self {
Self::new()
}
}
impl FloatingWindowBuilder {
pub fn new() -> Self {
Self { config: WindowConfig::new(), event_callback: None }
}
pub fn id(mut self, id: impl Into<String>) -> Self {
self.config.id = Some(id.into());
self
}
pub fn title(mut self, title: impl Into<String>) -> Self {
self.config.title = Some(title.into());
self
}
pub fn position(mut self, x: f64, y: f64) -> Self {
self.config.position = Position::new(x, y);
self
}
pub fn size(mut self, width: u32, height: u32) -> Self {
self.config.size = Size::new(width, height);
self
}
pub fn shape(mut self, shape: WindowShape) -> Self {
self.config.shape = shape;
self
}
pub fn draggable(mut self, draggable: bool) -> Self {
self.config.draggable = draggable;
self
}
pub fn resizable(mut self, resizable: bool) -> Self {
self.config.resizable = resizable;
self
}
pub fn click_through(mut self, click_through: bool) -> Self {
self.config.click_through = click_through;
self
}
pub fn level(mut self, level: WindowLevel) -> Self {
self.config.level = level;
self
}
pub fn always_on_top(mut self, always: bool) -> Self {
self.config.level = if always { WindowLevel::AlwaysOnTop } else { WindowLevel::Normal };
self
}
pub fn opacity(mut self, opacity: f32) -> Self {
self.config.opacity = opacity.clamp(0.0, 1.0);
self
}
pub fn icon(mut self, icon: WindowIcon) -> Self {
self.config.icon = Some(icon);
self
}
pub fn content(mut self, content: Content) -> Self {
self.config.content = Some(content);
self
}
pub fn effect(mut self, effect: PresetEffect, options: PresetEffectOptions) -> Self {
let (_, max_size) = options.particle_size;
let margin = max_size * 2.0 + options.edge_width + 10.0; self.config.effect_margin = margin;
self.config.effect = Some((effect, options));
self
}
pub fn effect_margin(mut self, margin: f32) -> Self {
self.config.effect_margin = margin;
self
}
pub fn show_animation(mut self, animation: WindowAnimation) -> Self {
self.config.show_animation = Some(animation);
self
}
pub fn hide_animation(mut self, animation: WindowAnimation) -> Self {
self.config.hide_animation = Some(animation);
self
}
pub fn on_event<F>(mut self, callback: F) -> Self
where
F: Fn(&FloatingWindowEvent) + Send + Sync + 'static,
{
self.event_callback = Some(Box::new(callback));
self
}
pub fn build(self) -> Result<FloatingWindow, String> {
FloatingWindow::from_config(self.config, self.event_callback)
}
}