fluent_app/
app_builder.rs1use std::sync::Arc;
2
3use fluent_core::Theme;
4use fluent_layout::{modal::ModalStack, ToastStack};
5use gpui::{
6 prelude::*, px, size, App, Application, AssetSource, Bounds, Entity, Render, SharedString,
7 TitlebarOptions, WindowBounds, WindowDecorations, WindowOptions,
8};
9
10use crate::{assets::FluentAssets, title_bar::TitleBar};
11
12const DEFAULT_W: f32 = 1280.0;
13const DEFAULT_H: f32 = 800.0;
14
15pub struct FluentApp {
25 title: SharedString,
26 window_w: f32,
27 window_h: f32,
28 dark: bool,
29 assets: Option<Arc<dyn AssetSource>>,
30}
31
32impl FluentApp {
33 pub fn new(title: impl Into<SharedString>) -> Self {
34 Self {
35 title: title.into(),
36 window_w: DEFAULT_W,
37 window_h: DEFAULT_H,
38 dark: true,
39 assets: None,
40 }
41 }
42
43 pub fn window_size(mut self, w: f32, h: f32) -> Self {
44 self.window_w = w;
45 self.window_h = h;
46 self
47 }
48
49 pub fn dark_theme(mut self) -> Self {
50 self.dark = true;
51 self
52 }
53
54 pub fn light_theme(mut self) -> Self {
55 self.dark = false;
56 self
57 }
58
59 pub fn assets(mut self, assets: impl AssetSource) -> Self {
60 self.assets = Some(Arc::new(assets));
61 self
62 }
63
64 pub fn run<V: Render + 'static>(self, build: impl FnOnce(&mut App) -> Entity<V> + 'static) {
69 let title = self.title.clone();
70 let w = self.window_w;
71 let h = self.window_h;
72 let dark = self.dark;
73 let assets = self.assets;
74
75 Application::new()
76 .with_assets(FluentAssets::new(assets))
77 .run(move |cx: &mut App| {
78 if dark {
79 Theme::init(cx);
80 } else {
81 cx.set_global(Theme::light());
82 }
83 ModalStack::init(cx);
84 ToastStack::init(cx);
85
86 let bounds = Bounds::centered(None, size(px(w), px(h)), cx);
87
88 cx.open_window(
89 WindowOptions {
90 window_bounds: Some(WindowBounds::Windowed(bounds)),
91 titlebar: Some(TitlebarOptions {
92 title: Some(title.clone()),
93 appears_transparent: true,
94 traffic_light_position: None,
95 }),
96 window_decorations: Some(WindowDecorations::Client),
97 ..Default::default()
98 },
99 move |_window, cx: &mut App| build(cx),
100 )
101 .unwrap();
102
103 cx.activate(true);
104 });
105 }
106}
107
108pub fn title_bar(title: impl Into<SharedString>, cx: &mut App) -> Entity<TitleBar> {
110 let t = title.into();
111 cx.new(|cx| TitleBar::new(cx, t))
112}