`gpui_web` currently embeds IBM Plex Sans and Lilex into every browser application during platform construction. Applications such as Delta already provide their own fonts, so those binaries contain overlapping font bundles and register the same faces twice. This change starts the web platform with an empty font database, matching the ownership boundary used by native applications: the application selects and registers its fonts before opening a window. Delta already follows that sequence. GPUI's browser-capable examples now load the former eight-face bundle explicitly through shared example support, while the standalone `hello_web` example demonstrates registering a minimal application font directly. Testing performed: - `cargo check -p gpui --examples --target wasm32-unknown-unknown` - `cargo check -p gpui --examples` - `cargo check -p gpui_web --target wasm32-unknown-unknown` - `cargo check --manifest-path crates/gpui_web/examples/hello_web/Cargo.toml --target wasm32-unknown-unknown` - `./script/clippy -p gpui_web --target wasm32-unknown-unknown` - `cargo fmt -p gpui -p gpui_web --check` Release Notes: - N/A
224 lines
7.0 KiB
Rust
224 lines
7.0 KiB
Rust
#![cfg_attr(target_family = "wasm", no_main)]
|
|
|
|
#[path = "../example_support/fonts.rs"]
|
|
mod example_support;
|
|
|
|
use std::fs;
|
|
use std::path::PathBuf;
|
|
use std::sync::Arc;
|
|
|
|
use anyhow::Result;
|
|
use gpui::{
|
|
App, AppContext, AssetSource, Bounds, Context, ImageSource, KeyBinding, Menu, MenuItem, Point,
|
|
SharedString, SharedUri, TitlebarOptions, Window, WindowBounds, WindowOptions, actions, div,
|
|
img, prelude::*, px, rgb, size,
|
|
};
|
|
#[cfg(not(target_family = "wasm"))]
|
|
use reqwest_client::ReqwestClient;
|
|
|
|
struct Assets {
|
|
base: PathBuf,
|
|
}
|
|
|
|
impl AssetSource for Assets {
|
|
fn load(&self, path: &str) -> Result<Option<std::borrow::Cow<'static, [u8]>>> {
|
|
fs::read(self.base.join(path))
|
|
.map(|data| Some(std::borrow::Cow::Owned(data)))
|
|
.map_err(|e| e.into())
|
|
}
|
|
|
|
fn list(&self, path: &str) -> Result<Vec<SharedString>> {
|
|
fs::read_dir(self.base.join(path))
|
|
.map(|entries| {
|
|
entries
|
|
.filter_map(|entry| {
|
|
entry
|
|
.ok()
|
|
.and_then(|entry| entry.file_name().into_string().ok())
|
|
.map(SharedString::from)
|
|
})
|
|
.collect()
|
|
})
|
|
.map_err(|e| e.into())
|
|
}
|
|
}
|
|
|
|
#[derive(IntoElement)]
|
|
struct ImageContainer {
|
|
text: SharedString,
|
|
src: ImageSource,
|
|
}
|
|
|
|
impl ImageContainer {
|
|
pub fn new(text: impl Into<SharedString>, src: impl Into<ImageSource>) -> Self {
|
|
Self {
|
|
text: text.into(),
|
|
src: src.into(),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl RenderOnce for ImageContainer {
|
|
fn render(self, _window: &mut Window, _: &mut App) -> impl IntoElement {
|
|
div().child(
|
|
div()
|
|
.flex_row()
|
|
.size_full()
|
|
.gap_4()
|
|
.child(self.text)
|
|
.child(img(self.src).size(px(256.0))),
|
|
)
|
|
}
|
|
}
|
|
|
|
struct ImageShowcase {
|
|
local_resource: Arc<std::path::Path>,
|
|
remote_resource: SharedUri,
|
|
asset_resource: SharedString,
|
|
}
|
|
|
|
impl Render for ImageShowcase {
|
|
fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
|
|
div()
|
|
.id("main")
|
|
.bg(gpui::white())
|
|
.overflow_y_scroll()
|
|
.p_5()
|
|
.size_full()
|
|
.child(
|
|
div()
|
|
.flex()
|
|
.flex_col()
|
|
.justify_center()
|
|
.items_center()
|
|
.gap_8()
|
|
.child(img(
|
|
"https://github.com/zed-industries/zed/actions/workflows/ci.yml/badge.svg",
|
|
))
|
|
.child(
|
|
div()
|
|
.flex()
|
|
.flex_row()
|
|
.justify_center()
|
|
.items_center()
|
|
.gap_8()
|
|
.child(ImageContainer::new(
|
|
"Image loaded from a local file with EXIF orientation",
|
|
self.local_resource.clone(),
|
|
))
|
|
.child(ImageContainer::new(
|
|
"Image loaded from a remote resource",
|
|
self.remote_resource.clone(),
|
|
))
|
|
.child(ImageContainer::new(
|
|
"Image loaded from an asset",
|
|
self.asset_resource.clone(),
|
|
)),
|
|
)
|
|
.child(
|
|
div()
|
|
.flex()
|
|
.flex_row()
|
|
.gap_8()
|
|
.child(
|
|
div()
|
|
.flex_col()
|
|
.child("Auto Width")
|
|
.child(img("https://picsum.photos/800/400").h(px(180.))),
|
|
)
|
|
.child(
|
|
div()
|
|
.flex_col()
|
|
.child("Auto Height")
|
|
.child(img("https://picsum.photos/800/400").w(px(180.))),
|
|
),
|
|
)
|
|
.child(
|
|
div()
|
|
.flex()
|
|
.flex_col()
|
|
.justify_center()
|
|
.items_center()
|
|
.w_full()
|
|
.border_1()
|
|
.border_color(rgb(0xC0C0C0))
|
|
.child("image with max width 100%")
|
|
.child(img("https://picsum.photos/800/400").max_w_full()),
|
|
),
|
|
)
|
|
}
|
|
}
|
|
|
|
actions!(image, [Quit]);
|
|
|
|
fn run_example() {
|
|
let manifest_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
|
|
|
#[cfg(not(target_family = "wasm"))]
|
|
let app = gpui_platform::application();
|
|
#[cfg(target_family = "wasm")]
|
|
let app = gpui_platform::application();
|
|
app.with_assets(Assets {
|
|
base: manifest_dir.join("examples"),
|
|
})
|
|
.run(move |cx: &mut App| {
|
|
if !example_support::load_fonts(cx) {
|
|
return;
|
|
}
|
|
#[cfg(not(target_family = "wasm"))]
|
|
{
|
|
let http_client = ReqwestClient::user_agent("gpui example").unwrap();
|
|
cx.set_http_client(Arc::new(http_client));
|
|
}
|
|
|
|
cx.activate(true);
|
|
cx.on_action(|_: &Quit, cx| cx.quit());
|
|
cx.bind_keys([KeyBinding::new("cmd-q", Quit, None)]);
|
|
cx.set_menus(vec![Menu {
|
|
name: "Image".into(),
|
|
items: vec![MenuItem::action("Quit", Quit)],
|
|
disabled: false,
|
|
}]);
|
|
|
|
let window_options = WindowOptions {
|
|
titlebar: Some(TitlebarOptions {
|
|
title: Some(SharedString::from("Image Example")),
|
|
appears_transparent: false,
|
|
..Default::default()
|
|
}),
|
|
|
|
window_bounds: Some(WindowBounds::Windowed(Bounds {
|
|
size: size(px(1100.), px(600.)),
|
|
origin: Point::new(px(200.), px(200.)),
|
|
})),
|
|
|
|
..Default::default()
|
|
};
|
|
|
|
cx.open_window(window_options, |_, cx| {
|
|
cx.new(|_| ImageShowcase {
|
|
// Relative path to your root project path
|
|
local_resource: manifest_dir
|
|
.join("examples/image/exif-orientation-rotate-180.jpg")
|
|
.into(),
|
|
remote_resource: "https://picsum.photos/800/400".into(),
|
|
asset_resource: "image/color.svg".into(),
|
|
})
|
|
})
|
|
.unwrap();
|
|
});
|
|
}
|
|
|
|
#[cfg(not(target_family = "wasm"))]
|
|
fn main() {
|
|
env_logger::init();
|
|
run_example();
|
|
}
|
|
|
|
#[cfg(target_family = "wasm")]
|
|
#[wasm_bindgen::prelude::wasm_bindgen(start)]
|
|
pub fn start() {
|
|
gpui_platform::web_init();
|
|
run_example();
|
|
}
|