image.rs

  1use std::path::PathBuf;
  2use std::str::FromStr;
  3use std::sync::Arc;
  4
  5use gpui::*;
  6use std::fs;
  7
  8struct Assets {
  9    base: PathBuf,
 10}
 11
 12impl AssetSource for Assets {
 13    fn load(&self, path: &str) -> Result<Option<std::borrow::Cow<'static, [u8]>>> {
 14        fs::read(self.base.join(path))
 15            .map(|data| Some(std::borrow::Cow::Owned(data)))
 16            .map_err(|e| e.into())
 17    }
 18
 19    fn list(&self, path: &str) -> Result<Vec<SharedString>> {
 20        fs::read_dir(self.base.join(path))
 21            .map(|entries| {
 22                entries
 23                    .filter_map(|entry| {
 24                        entry
 25                            .ok()
 26                            .and_then(|entry| entry.file_name().into_string().ok())
 27                            .map(SharedString::from)
 28                    })
 29                    .collect()
 30            })
 31            .map_err(|e| e.into())
 32    }
 33}
 34
 35#[derive(IntoElement)]
 36struct ImageContainer {
 37    text: SharedString,
 38    src: ImageSource,
 39}
 40
 41impl ImageContainer {
 42    pub fn new(text: impl Into<SharedString>, src: impl Into<ImageSource>) -> Self {
 43        Self {
 44            text: text.into(),
 45            src: src.into(),
 46        }
 47    }
 48}
 49
 50impl RenderOnce for ImageContainer {
 51    fn render(self, _: &mut WindowContext) -> impl IntoElement {
 52        div().child(
 53            div()
 54                .flex_row()
 55                .size_full()
 56                .gap_4()
 57                .child(self.text)
 58                .child(img(self.src).w(px(256.0)).h(px(256.0))),
 59        )
 60    }
 61}
 62
 63struct ImageShowcase {
 64    local_resource: Arc<PathBuf>,
 65    remote_resource: SharedUri,
 66    asset_resource: SharedString,
 67}
 68
 69impl Render for ImageShowcase {
 70    fn render(&mut self, _cx: &mut ViewContext<Self>) -> impl IntoElement {
 71        div()
 72            .flex()
 73            .flex_row()
 74            .size_full()
 75            .justify_center()
 76            .items_center()
 77            .gap_8()
 78            .bg(rgb(0xFFFFFF))
 79            .child(ImageContainer::new(
 80                "Image loaded from a local file",
 81                self.local_resource.clone(),
 82            ))
 83            .child(ImageContainer::new(
 84                "Image loaded from a remote resource",
 85                self.remote_resource.clone(),
 86            ))
 87            .child(ImageContainer::new(
 88                "Image loaded from an asset",
 89                self.asset_resource.clone(),
 90            ))
 91    }
 92}
 93
 94actions!(image, [Quit]);
 95
 96fn main() {
 97    env_logger::init();
 98
 99    App::new()
100        .with_assets(Assets {
101            base: PathBuf::from("crates/gpui/examples"),
102        })
103        .run(|cx: &mut AppContext| {
104            cx.activate(true);
105            cx.on_action(|_: &Quit, cx| cx.quit());
106            cx.bind_keys([KeyBinding::new("cmd-q", Quit, None)]);
107            cx.set_menus(vec![Menu {
108                name: "Image".into(),
109                items: vec![MenuItem::action("Quit", Quit)],
110            }]);
111
112            let window_options = WindowOptions {
113                titlebar: Some(TitlebarOptions {
114                    title: Some(SharedString::from("Image Example")),
115                    appears_transparent: false,
116                    ..Default::default()
117                }),
118
119                window_bounds: Some(WindowBounds::Windowed(Bounds {
120                    size: size(px(1100.), px(600.)),
121                    origin: Point::new(px(200.), px(200.)),
122                })),
123
124                ..Default::default()
125            };
126
127            cx.open_window(window_options, |cx| {
128                cx.new_view(|_cx| ImageShowcase {
129                    // Relative path to your root project path
130                    local_resource: Arc::new(
131                        PathBuf::from_str("crates/gpui/examples/image/app-icon.png").unwrap(),
132                    ),
133                    remote_resource: "https://picsum.photos/512/512".into(),
134
135                    asset_resource: "image/color.svg".into(),
136                })
137            })
138            .unwrap();
139        });
140}