use crate::element::IntoElement;
use crate::reactive::Owner;
use ferroui_base::Ref;
use ferroui_controls::{AppBuilder, Application, Window, WindowBaseImpl};
use ferroui_desktop::AppBuilderDesktopExtensions;
use ferroui_base::styling::IStyle;
use ferroui_themes_fluent::FluentTheme;
use std::rc::Rc;
pub fn mount_window(view: impl FnOnce() -> crate::Element) -> Ref<Window> {
let owner = Owner::new_root();
let window = owner.with(|| {
let control = view().into_element().mount();
match control.cast::<Window>() {
Some(window) => window,
None => {
let window = Window::new();
window.set_content(Some(ferroui_controls::Control::boxed(&control)));
window
}
}
});
let _closed = window.closed(move || owner.dispose());
window
}
pub fn open_window(view: impl FnOnce() -> crate::Element) -> Ref<Window> {
let window = mount_window(view);
WindowBaseImpl::show(&*window);
window
}
pub fn launch(view: impl FnOnce() -> crate::Element + 'static) {
launch_with(view, |_| {});
}
pub fn launch_with(view: impl FnOnce() -> crate::Element + 'static, started: impl FnOnce(&Ref<Window>) + 'static) {
launch_themed(|| FluentTheme::new().as_style(), view, started);
}
pub fn launch_themed(
theme: impl FnOnce() -> Rc<dyn IStyle> + 'static,
view: impl FnOnce() -> crate::Element + 'static,
started: impl FnOnce(&Ref<Window>) + 'static,
) {
let args: Vec<String> = std::env::args().skip(1).collect();
AppBuilder::configure::<Application>().use_platform_detect().start(
move |app, _| {
app.styles().add(theme());
let window = mount_window(view);
smoke_exit(&window);
started(&window);
app.run_window(window);
},
&args,
);
}
fn smoke_exit(window: &Ref<Window>) {
if let Some(ms) = std::env::var("FERROUI_SMOKE_EXIT_MS").ok().and_then(|value| value.parse::<u64>().ok()) {
let window = window.clone();
let _timer = ferroui_base::threading::DispatcherTimer::run_once(
move || window.close(),
std::time::Duration::from_millis(ms),
ferroui_base::threading::DispatcherPriority::NORMAL,
);
}
}