1#![cfg_attr(target_family = "wasm", no_main)]
2
3use std::{fs, path::PathBuf};
4
5use anyhow::Result;
6use gpui::{
7 App, AssetSource, Bounds, BoxShadow, ClickEvent, Context, SharedString, Task, Window,
8 WindowBounds, WindowOptions, div, hsla, img, point, prelude::*, px, rgb, size, svg,
9};
10use gpui_platform::application;
11
12struct Assets {
13 base: PathBuf,
14}
15
16impl AssetSource for Assets {
17 fn load(&self, path: &str) -> Result<Option<std::borrow::Cow<'static, [u8]>>> {
18 fs::read(self.base.join(path))
19 .map(|data| Some(std::borrow::Cow::Owned(data)))
20 .map_err(|e| e.into())
21 }
22
23 fn list(&self, path: &str) -> Result<Vec<SharedString>> {
24 fs::read_dir(self.base.join(path))
25 .map(|entries| {
26 entries
27 .filter_map(|entry| {
28 entry
29 .ok()
30 .and_then(|entry| entry.file_name().into_string().ok())
31 .map(SharedString::from)
32 })
33 .collect()
34 })
35 .map_err(|e| e.into())
36 }
37}
38
39struct HelloWorld {
40 _task: Option<Task<()>>,
41 opacity: f32,
42 animating: bool,
43}
44
45impl HelloWorld {
46 fn new(_window: &mut Window, _: &mut Context<Self>) -> Self {
47 Self {
48 _task: None,
49 opacity: 0.5,
50 animating: false,
51 }
52 }
53
54 fn start_animation(&mut self, _: &ClickEvent, _: &mut Window, cx: &mut Context<Self>) {
55 self.opacity = 0.0;
56 self.animating = true;
57 cx.notify();
58 }
59}
60
61impl Render for HelloWorld {
62 fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
63 if self.animating {
64 self.opacity += 0.005;
65 if self.opacity >= 1.0 {
66 self.animating = false;
67 self.opacity = 1.0;
68 } else {
69 window.request_animation_frame();
70 }
71 }
72
73 div()
74 .flex()
75 .flex_row()
76 .size_full()
77 .bg(rgb(0xe0e0e0))
78 .text_xl()
79 .child(
80 div()
81 .flex()
82 .size_full()
83 .justify_center()
84 .items_center()
85 .border_1()
86 .text_color(gpui::blue())
87 .child(div().child("This is background text.")),
88 )
89 .child(
90 div()
91 .id("panel")
92 .on_click(cx.listener(Self::start_animation))
93 .absolute()
94 .top_8()
95 .left_8()
96 .right_8()
97 .bottom_8()
98 .opacity(self.opacity)
99 .flex()
100 .justify_center()
101 .items_center()
102 .bg(gpui::white())
103 .border_3()
104 .border_color(gpui::red())
105 .text_color(gpui::yellow())
106 .child(
107 div()
108 .flex()
109 .flex_col()
110 .gap_2()
111 .justify_center()
112 .items_center()
113 .size(px(300.))
114 .bg(gpui::blue())
115 .border_3()
116 .border_color(gpui::black())
117 .shadow(vec![BoxShadow {
118 color: hsla(0.0, 0.0, 0.0, 0.5),
119 blur_radius: px(1.0),
120 spread_radius: px(5.0),
121 offset: point(px(10.0), px(10.0)),
122 }])
123 .child(img("image/app-icon.png").size_8())
124 .child("Opacity Panel (Click to test)")
125 .child(
126 div()
127 .id("deep-level-text")
128 .flex()
129 .justify_center()
130 .items_center()
131 .p_4()
132 .bg(gpui::black())
133 .text_color(gpui::white())
134 .text_decoration_2()
135 .text_decoration_wavy()
136 .text_decoration_color(gpui::red())
137 .child(format!("opacity: {:.1}", self.opacity)),
138 )
139 .child(
140 svg()
141 .path("image/arrow_circle.svg")
142 .text_color(gpui::black())
143 .text_2xl()
144 .size_8(),
145 )
146 .child(
147 div()
148 .flex()
149 .children(["🎊", "✈️", "🎉", "🎈", "🎁", "🎂"].map(|emoji| {
150 div()
151 .child(emoji.to_string())
152 .hover(|style| style.opacity(0.5))
153 })),
154 )
155 .child(img("image/black-cat-typing.gif").size_12()),
156 ),
157 )
158 }
159}
160
161fn run_example() {
162 application()
163 .with_assets(Assets {
164 base: PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("examples"),
165 })
166 .run(|cx: &mut App| {
167 let bounds = Bounds::centered(None, size(px(500.0), px(500.0)), cx);
168 cx.open_window(
169 WindowOptions {
170 window_bounds: Some(WindowBounds::Windowed(bounds)),
171 ..Default::default()
172 },
173 |window, cx| cx.new(|cx| HelloWorld::new(window, cx)),
174 )
175 .unwrap();
176 cx.activate(true);
177 });
178}
179
180#[cfg(not(target_family = "wasm"))]
181fn main() {
182 run_example();
183}
184
185#[cfg(target_family = "wasm")]
186#[wasm_bindgen::prelude::wasm_bindgen(start)]
187pub fn start() {
188 gpui_platform::web_init();
189 run_example();
190}