T44d Web · What a browser cannot do says why; fonts resolve; the bundle builds
Demos that open a second window, take files, move the window, read the clipboard or set native menus show a note on the web in the blocked style. IBM Plex Sans Regular joins the assets, unmodified, where gpui's svg renderer loads it: gpui_web answers .SystemUIFont with it. The gallery's web entry registers a Hebrew cut of Noto Sans Hebrew. scripts/web.sh builds the bundle with wasm-bindgen and wasm-opt -Oz, 20.0 MB, and fails past 25 MiB.
This commit is contained in:
1 parent
48c7b09d8d
commit
2cd2ca8bc1
26 files changed
+381
-76
No files matched your search
@@ -0,0 +1,92 @@
|
||||
Copyright 2022 The Noto Project Authors (https://github.com/notofonts/hebrew)
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION AND CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
Binary file not shown.
@@ -12,7 +12,7 @@ use gpui::{App, IntoElement, ParentElement, SharedString, Styled, Window, div, p
|
||||
|
||||
use crate::{
|
||||
probe::probe,
|
||||
ui::{change, keep, section},
|
||||
ui::{NO_FILES, change, keep, section, web_note},
|
||||
};
|
||||
|
||||
/// The switchers' demo: the account and workspace in use.
|
||||
@@ -115,6 +115,7 @@ pub fn profile(window: &mut Window, cx: &mut App) -> impl IntoElement + use<> {
|
||||
"Someone at a glance, and their profile to edit: Save waits for a change, a name and an email that reads; Discard puts the saved profile back.",
|
||||
cx,
|
||||
)
|
||||
.children(web_note(NO_FILES, cx))
|
||||
.child(
|
||||
div()
|
||||
.flex()
|
||||
|
||||
@@ -15,7 +15,7 @@ use web_time::Instant;
|
||||
|
||||
use crate::{
|
||||
probe::probe,
|
||||
ui::{keep, noise, section, set},
|
||||
ui::{NO_FILES, keep, noise, section, set, web_note},
|
||||
};
|
||||
|
||||
const SYSTEM: &str = "You answer about color in plain words. Cite sources.";
|
||||
@@ -160,6 +160,7 @@ pub fn composer(
|
||||
"Where a message is written: attachments and context above the field, tools below, send at the end; Enter sends and Shift-Enter breaks the line. A slash at the start offers commands, an at sign offers context, and files dropped on it attach.",
|
||||
cx,
|
||||
)
|
||||
.children(web_note(NO_FILES, cx))
|
||||
.child(probe(
|
||||
"chat-composer",
|
||||
div()
|
||||
|
||||
@@ -15,7 +15,7 @@ use gpui::{App, IntoElement, ParentElement, SharedString, Styled, Window, div};
|
||||
|
||||
use crate::{
|
||||
probe::probe,
|
||||
ui::{keep, picture, row, section, set, specimen, specimens},
|
||||
ui::{NO_FILES, keep, picture, row, section, set, specimen, specimens, web_note},
|
||||
};
|
||||
|
||||
const DUNES: &str = asset!("dunes-square.jpg");
|
||||
@@ -119,6 +119,7 @@ pub fn avatars(window: &mut Window, cx: &mut App) -> impl IntoElement + use<> {
|
||||
"A picture, or initials on a tone the name keeps, or an icon. Presence sits on the corner. Hover the last one, then press it to choose a picture, or drop one on it.",
|
||||
cx,
|
||||
)
|
||||
.children(web_note(NO_FILES, cx))
|
||||
.child(specimens().children(sizes.map(|(size, name)| {
|
||||
specimen(name, Avatar::new(SharedString::from(format!("avatar-{name}")), "Kofi Mensah").size(size), cx)
|
||||
})))
|
||||
|
||||
@@ -10,7 +10,7 @@ use jiff::Timestamp;
|
||||
|
||||
use crate::{
|
||||
probe::probe,
|
||||
ui::{change, keep, section},
|
||||
ui::{NO_FILES, change, keep, section, web_note},
|
||||
};
|
||||
|
||||
pub fn context_menu(cx: &mut App) -> impl IntoElement + use<> {
|
||||
@@ -84,6 +84,7 @@ pub fn drop_files(window: &mut Window, cx: &mut App) -> impl IntoElement + use<>
|
||||
"Files dropped in, as forms::DropZone takes them; each lands in the list below.",
|
||||
cx,
|
||||
)
|
||||
.children(web_note(NO_FILES, cx))
|
||||
.child(probe(
|
||||
"files-drop",
|
||||
div()
|
||||
|
||||
@@ -5,7 +5,7 @@ use gpui::{App, IntoElement, ParentElement, Styled, Window, div, px};
|
||||
|
||||
use crate::{
|
||||
probe::probe,
|
||||
ui::{keep, section, set, specimen, specimens},
|
||||
ui::{NO_FILES, keep, section, set, specimen, specimens, web_note},
|
||||
};
|
||||
|
||||
fn names(paths: &[PathBuf]) -> String {
|
||||
@@ -44,6 +44,7 @@ pub fn files(window: &mut Window, cx: &mut App) -> impl IntoElement + use<> {
|
||||
"Click a field or Browse for the system's dialog, or drop files from Finder. A folder, or two files on a one-file target, turns it red.",
|
||||
cx,
|
||||
)
|
||||
.children(web_note(NO_FILES, cx))
|
||||
.child(
|
||||
specimens()
|
||||
.child(specimen(
|
||||
|
||||
@@ -10,7 +10,7 @@ use gpui::{App, IntoElement, Keystroke, ParentElement, SharedString, Styled, Win
|
||||
use super::text::field;
|
||||
use crate::{
|
||||
probe::probe,
|
||||
ui::{code, section},
|
||||
ui::{NO_FILES, code, section, web_note},
|
||||
};
|
||||
|
||||
pub fn mention(window: &mut Window, cx: &mut App) -> impl IntoElement + use<> {
|
||||
@@ -99,6 +99,7 @@ pub fn path(window: &mut Window, cx: &mut App) -> impl IntoElement + use<> {
|
||||
"Type a path, or Browse with the system's dialog.",
|
||||
cx,
|
||||
)
|
||||
.children(web_note(NO_FILES, cx))
|
||||
.child(probe(
|
||||
"path",
|
||||
div()
|
||||
|
||||
@@ -9,7 +9,7 @@ use gpui::{App, IntoElement, ParentElement, SharedString, Styled, Window, div, p
|
||||
|
||||
use crate::{
|
||||
probe::probe,
|
||||
ui::{keep, picture, section, set},
|
||||
ui::{keep, picture, section, set, web_note},
|
||||
};
|
||||
|
||||
const ATRIUM: &str = asset!("atrium.jpg");
|
||||
@@ -106,6 +106,10 @@ pub fn upload(window: &mut Window, cx: &mut App) -> impl IntoElement + use<> {
|
||||
"A picture to send: drop one or browse for it, then crop it. Replace picks another; Remove empties it.",
|
||||
cx,
|
||||
)
|
||||
.children(web_note(
|
||||
"A browser hands gpui no files: on the web the file dialog fails, drops never arrive, and the picture this starts with, a file on disk, cannot be read.",
|
||||
cx,
|
||||
))
|
||||
.child(probe(
|
||||
"media-upload",
|
||||
div().w(px(420.)).child(
|
||||
|
||||
@@ -9,16 +9,27 @@ use gpui::{App, IntoElement, ParentElement, Styled, Window, div, px};
|
||||
use super::rows::{ran, run};
|
||||
use crate::{
|
||||
probe::probe,
|
||||
ui::{section, specimen},
|
||||
ui::{section, specimen, web_note},
|
||||
};
|
||||
|
||||
pub fn menu_bar(cx: &mut App) -> impl IntoElement + use<> {
|
||||
let menus = cx.get_menus().expect("the gallery sets its menus in main");
|
||||
let menus = match cx.get_menus() {
|
||||
Some(menus) => menus,
|
||||
None if cfg!(target_family = "wasm") => crate::app_menus()
|
||||
.into_iter()
|
||||
.map(gpui::Menu::owned)
|
||||
.collect(),
|
||||
None => panic!("the gallery sets its menus in main"),
|
||||
};
|
||||
section(
|
||||
"MenuBar Menu",
|
||||
"The app's own menus, the ones cx.set_menus gave the system, drawn in the window. Picking a row dispatches its action.",
|
||||
cx,
|
||||
)
|
||||
.children(web_note(
|
||||
"A browser page has no menu bar, and gpui on the web keeps no cx.set_menus: this bar draws the gallery's own list of the same menus.",
|
||||
cx,
|
||||
))
|
||||
.child(specimen(
|
||||
"hover moves between menus while one is open",
|
||||
probe("menubar", MenuBar::new("app-bar", menus)),
|
||||
|
||||
@@ -8,7 +8,7 @@ use gpui::{App, Entity, IntoElement, ParentElement, SharedString, Window};
|
||||
|
||||
use crate::{
|
||||
probe::{Opened, probe},
|
||||
ui::{keep, row, section, set, specimen},
|
||||
ui::{keep, own_window, row, section, set, specimen},
|
||||
};
|
||||
|
||||
/// Moves `value` to the front of a recent list, keeping `size` entries.
|
||||
@@ -398,7 +398,7 @@ pub fn search_palette(window: &mut Window, cx: &mut App) -> impl IntoElement + u
|
||||
))
|
||||
.child(specimen(
|
||||
"a window above all others",
|
||||
probe(
|
||||
own_window(probe(
|
||||
"launcher",
|
||||
Button::new("launcher-button", "Open the launcher")
|
||||
.variant(ButtonVariant::Ghost)
|
||||
@@ -415,7 +415,7 @@ pub fn search_palette(window: &mut Window, cx: &mut App) -> impl IntoElement + u
|
||||
Err(error) => log::error!("gallery: launcher: {error:#}"),
|
||||
}
|
||||
}),
|
||||
),
|
||||
), cx),
|
||||
cx,
|
||||
)),
|
||||
)
|
||||
|
||||
@@ -13,7 +13,7 @@ use gpui::{
|
||||
|
||||
use crate::{
|
||||
probe::probe,
|
||||
ui::{code, row, section},
|
||||
ui::{code, row, section, web_note},
|
||||
};
|
||||
|
||||
pub fn boxes(cx: &App) -> impl IntoElement + use<> {
|
||||
@@ -445,6 +445,10 @@ pub fn clipboard(window: &mut Window, cx: &mut App) -> impl IntoElement + use<>
|
||||
"write_to_clipboard and read_from_clipboard on App.",
|
||||
cx,
|
||||
)
|
||||
.children(web_note(
|
||||
"A browser reads its clipboard only as it pastes, into a field: on the web gpui's read_from_clipboard finds nothing, so Paste reports no text. Copy works.",
|
||||
cx,
|
||||
))
|
||||
.child(
|
||||
row()
|
||||
.gap_3()
|
||||
|
||||
@@ -11,7 +11,7 @@ use ely_gpui_component::{
|
||||
use gpui::{AnyElement, App, Entity, IntoElement, ParentElement, Styled, div, px};
|
||||
|
||||
use super::window::{Fields, Prefs, SIZE};
|
||||
use crate::ui::change;
|
||||
use crate::ui::{NO_FILES, change, web_note};
|
||||
|
||||
/// The open section's page.
|
||||
pub(super) fn page(prefs: &Entity<Prefs>, fields: &Fields, section: &str, cx: &App) -> AnyElement {
|
||||
@@ -198,6 +198,7 @@ fn storage(prefs: &Entity<Prefs>, cx: &App) -> AnyElement {
|
||||
}),
|
||||
),
|
||||
)
|
||||
.children(web_note(NO_FILES, cx))
|
||||
.child(
|
||||
SettingsSection::new("Defaults")
|
||||
.description("A larger font size shows here.")
|
||||
|
||||
@@ -7,7 +7,7 @@ use ely_gpui_component::{
|
||||
};
|
||||
use gpui::{App, Div, IntoElement, ParentElement, Styled, Window, div, px};
|
||||
|
||||
use crate::ui::{code, row, section, specimen, specimens};
|
||||
use crate::ui::{code, row, section, specimen, specimens, web_note};
|
||||
|
||||
/// A window drawn inside the page.
|
||||
pub fn window_frame(width: f32, height: f32, cx: &App) -> Div {
|
||||
@@ -116,6 +116,10 @@ pub fn window_controls(cx: &App) -> impl IntoElement + use<> {
|
||||
"Minimize and zoom act on this window. Close here only logs.",
|
||||
cx,
|
||||
))
|
||||
.children(web_note(
|
||||
"A browser owns the page's window: gpui on the web only logs minimize and zoom.",
|
||||
cx,
|
||||
))
|
||||
}
|
||||
|
||||
pub fn drag_area(window: &mut Window, cx: &mut App) -> impl IntoElement + use<> {
|
||||
@@ -142,6 +146,10 @@ pub fn drag_area(window: &mut Window, cx: &mut App) -> impl IntoElement + use<>
|
||||
.child("Double-click to zoom this window"),
|
||||
)
|
||||
.child(code("drag_region(id, window, cx)", cx))
|
||||
.children(web_note(
|
||||
"A browser owns the page's window: gpui on the web neither moves nor zooms it.",
|
||||
cx,
|
||||
))
|
||||
}
|
||||
|
||||
pub fn resize_border(cx: &App) -> impl IntoElement + use<> {
|
||||
@@ -154,6 +162,10 @@ pub fn resize_border(cx: &App) -> impl IntoElement + use<> {
|
||||
"Linux draws its own edges. This macOS window keeps the system's, so the border lays out only.",
|
||||
))
|
||||
.child(code("ResizeBorder::new().child(app)", cx))
|
||||
.children(web_note(
|
||||
"A browser sizes the page's canvas itself: gpui on the web resizes no window from its edges.",
|
||||
cx,
|
||||
))
|
||||
}
|
||||
|
||||
pub fn menus(cx: &App) -> impl IntoElement + use<> {
|
||||
@@ -177,4 +189,8 @@ pub fn menus(cx: &App) -> impl IntoElement + use<> {
|
||||
.child(Caption::new(
|
||||
"MenuBar draws the same menus inside the window. It lands with Menus, chapter 8.",
|
||||
))
|
||||
.children(web_note(
|
||||
"A browser page has no menu bar and no Dock: gpui on the web keeps neither cx.set_menus nor cx.set_dock_menu.",
|
||||
cx,
|
||||
))
|
||||
}
|
||||
@@ -11,7 +11,7 @@ use gpui::{App, IntoElement, ParentElement, Styled, Window, div};
|
||||
use super::chrome::window_frame;
|
||||
use crate::{
|
||||
probe::{Opened, probe},
|
||||
ui::{row, section, specimen},
|
||||
ui::{own_window, row, section, specimen},
|
||||
};
|
||||
|
||||
fn log_action(name: &'static str) -> impl Fn(&mut Window, &mut App) + 'static {
|
||||
@@ -59,14 +59,17 @@ pub fn update_window(cx: &App) -> impl IntoElement + use<> {
|
||||
.child(update_dialog().on_later(log_action("later"))),
|
||||
cx,
|
||||
))
|
||||
.child(probe(
|
||||
"update-open",
|
||||
Button::new("update-open", "Open update window")
|
||||
.variant(ButtonVariant::Outline)
|
||||
.on_click(|_, _, cx| match update_dialog().open(cx) {
|
||||
Ok(handle) => Opened::insert("update", handle.into(), cx),
|
||||
Err(error) => log::error!("gallery: update window failed: {error:#}"),
|
||||
}),
|
||||
.child(own_window(
|
||||
probe(
|
||||
"update-open",
|
||||
Button::new("update-open", "Open update window")
|
||||
.variant(ButtonVariant::Outline)
|
||||
.on_click(|_, _, cx| match update_dialog().open(cx) {
|
||||
Ok(handle) => Opened::insert("update", handle.into(), cx),
|
||||
Err(error) => log::error!("gallery: update window failed: {error:#}"),
|
||||
}),
|
||||
),
|
||||
cx,
|
||||
))
|
||||
}
|
||||
|
||||
@@ -101,14 +104,17 @@ pub fn crash_reporter(cx: &App) -> impl IntoElement + use<> {
|
||||
.child(reporter(true)),
|
||||
cx,
|
||||
))
|
||||
.child(probe(
|
||||
"crash-open",
|
||||
Button::new("crash-open", "Open crash window")
|
||||
.variant(ButtonVariant::Outline)
|
||||
.on_click(move |_, _, cx| match reporter(false).open(cx) {
|
||||
Ok(handle) => Opened::insert("crash", handle.into(), cx),
|
||||
Err(error) => log::error!("gallery: crash window failed: {error:#}"),
|
||||
}),
|
||||
.child(own_window(
|
||||
probe(
|
||||
"crash-open",
|
||||
Button::new("crash-open", "Open crash window")
|
||||
.variant(ButtonVariant::Outline)
|
||||
.on_click(move |_, _, cx| match reporter(false).open(cx) {
|
||||
Ok(handle) => Opened::insert("crash", handle.into(), cx),
|
||||
Err(error) => log::error!("gallery: crash window failed: {error:#}"),
|
||||
}),
|
||||
),
|
||||
cx,
|
||||
))
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ use gpui::{App, IntoElement, ParentElement, SharedString, Window};
|
||||
|
||||
use crate::{
|
||||
probe::probe,
|
||||
ui::{blocked, row, section},
|
||||
ui::{blocked, row, section, web_note},
|
||||
};
|
||||
|
||||
const ITEMS: [&str; 3] = ["Open gallery", "Toggle theme", "Quit"];
|
||||
@@ -23,6 +23,10 @@ pub fn tray(window: &mut Window, cx: &mut App) -> impl IntoElement + use<> {
|
||||
"An SF Symbol in the menu bar with a menu. macOS only.",
|
||||
cx,
|
||||
)
|
||||
.children(web_note(
|
||||
"A browser page has no menu bar to hold an icon, so showing one fails and logs why.",
|
||||
cx,
|
||||
))
|
||||
.child(
|
||||
row()
|
||||
.child(probe(
|
||||
@@ -113,6 +117,10 @@ pub fn dock(cx: &mut App) -> impl IntoElement + use<> {
|
||||
"A count on the app's Dock icon. macOS only.",
|
||||
cx,
|
||||
)
|
||||
.children(web_note(
|
||||
"A browser page has no Dock icon to badge, so setting one fails and logs why.",
|
||||
cx,
|
||||
))
|
||||
.child(
|
||||
row()
|
||||
.child(probe(
|
||||
@@ -138,7 +146,11 @@ pub fn notification(cx: &App) -> impl IntoElement + use<> {
|
||||
cx,
|
||||
)
|
||||
.child(blocked(
|
||||
"Not yet shown: gpui posts a system notification only from an app bundle, and the gallery runs unbundled.",
|
||||
if cfg!(target_family = "wasm") {
|
||||
"Not shown: gpui on the web posts no system notification."
|
||||
} else {
|
||||
"Not yet shown: gpui posts a system notification only from an app bundle, and the gallery runs unbundled."
|
||||
},
|
||||
cx,
|
||||
))
|
||||
}
|
||||
@@ -4,7 +4,7 @@ use ely_gpui_component::{
|
||||
};
|
||||
use gpui::{App, IntoElement, ParentElement, SharedString, Styled, Window, div, px};
|
||||
|
||||
use crate::ui::{change, keep, section, specimen, specimens};
|
||||
use crate::ui::{NO_FILES, change, keep, section, specimen, specimens, web_note};
|
||||
|
||||
/// Which code palette the demo last chose.
|
||||
struct Chosen(SharedString);
|
||||
@@ -17,6 +17,7 @@ pub fn importing(window: &mut Window, cx: &mut App) -> impl IntoElement + use<>
|
||||
"A VS Code color theme dropped here reads into Ely's palette, the colors it leaves out kept from Ely's; Apply sets it on the whole gallery. Code palettes choose the colors of code for the mode shown.",
|
||||
cx,
|
||||
)
|
||||
.children(web_note(NO_FILES, cx))
|
||||
.child(
|
||||
specimens()
|
||||
.child(specimen(
|
||||
|
||||
@@ -14,7 +14,7 @@ use gpui::{
|
||||
|
||||
use crate::{
|
||||
probe::{Opened, probe},
|
||||
ui::{change, keep, section, specimen, specimens},
|
||||
ui::{change, keep, native_only, section, specimen, specimens},
|
||||
};
|
||||
|
||||
const PLATFORMS: [(Platform, &str); 3] = [
|
||||
@@ -38,10 +38,14 @@ pub fn platform(window: &mut Window, cx: &mut App) -> impl IntoElement + use<> {
|
||||
.child(specimen("IconTheme", icons(window, cx), cx))
|
||||
.child(specimen(
|
||||
"Vibrancy",
|
||||
probe(
|
||||
"frosted-open",
|
||||
Button::new("frosted-open", "Open a frosted window")
|
||||
.on_click(|_, _, cx| frosted(cx)),
|
||||
native_only(
|
||||
probe(
|
||||
"frosted-open",
|
||||
Button::new("frosted-open", "Open a frosted window")
|
||||
.on_click(|_, _, cx| frosted(cx)),
|
||||
),
|
||||
"A browser page is a single window, and gpui leaves what lies behind it to the browser, so no frosted window opens and nothing blurs through.",
|
||||
cx,
|
||||
),
|
||||
cx,
|
||||
)),
|
||||
@@ -141,10 +145,10 @@ fn frosted(cx: &mut App) {
|
||||
window_background: WindowBackgroundAppearance::Blurred,
|
||||
..Default::default()
|
||||
};
|
||||
let handle = cx
|
||||
.open_window(options, |_, cx| cx.new(|_| Frosted))
|
||||
.expect("the frosted window opens");
|
||||
Opened::insert("frosted", handle.into(), cx);
|
||||
match cx.open_window(options, |_, cx| cx.new(|_| Frosted)) {
|
||||
Ok(handle) => Opened::insert("frosted", handle.into(), cx),
|
||||
Err(error) => log::error!("gallery: frosted window failed: {error:#}"),
|
||||
}
|
||||
}
|
||||
|
||||
/// A window whose sidebar lets the desktop through.
|
||||
|
||||
+22
-18
@@ -227,6 +227,19 @@ impl Gallery {
|
||||
}
|
||||
}
|
||||
|
||||
/// The window's root: the focus scope, over Ely's ground, ink and type.
|
||||
fn root(&self, cx: &App) -> FocusScope {
|
||||
let theme = cx.theme();
|
||||
FocusScope::new(&self.focus)
|
||||
.root()
|
||||
.size_full()
|
||||
.flex()
|
||||
.bg(theme.colors.bg)
|
||||
.text_color(theme.colors.fg)
|
||||
.font_family(theme.font_family.clone())
|
||||
.text_size(theme.text_size(TextSize::Base))
|
||||
}
|
||||
|
||||
/// The page's demos, or the story's alone; why not, once the start or the story failed.
|
||||
fn body(
|
||||
&mut self,
|
||||
@@ -259,24 +272,10 @@ impl Gallery {
|
||||
impl Render for Gallery {
|
||||
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
let page = &pages::ALL[self.page];
|
||||
let body = self.body(page, window, cx);
|
||||
let sidebar = self.sidebar(cx);
|
||||
let switcher = self.switcher(cx);
|
||||
let theme = cx.theme();
|
||||
let colors = &theme.colors;
|
||||
|
||||
let root = FocusScope::new(&self.focus)
|
||||
.root()
|
||||
.size_full()
|
||||
.flex()
|
||||
.bg(colors.bg)
|
||||
.text_color(colors.fg)
|
||||
.font_family(theme.font_family.clone())
|
||||
.text_size(theme.text_size(TextSize::Base));
|
||||
let body = match body {
|
||||
let body = match self.body(page, window, cx) {
|
||||
Ok(body) => body,
|
||||
Err(failure) => {
|
||||
return root.child(
|
||||
return self.root(cx).child(
|
||||
div().w_full().p_6().child(
|
||||
Alert::new("gallery-failure", Severity::Danger, "Nothing to show")
|
||||
.body(failure),
|
||||
@@ -285,7 +284,7 @@ impl Render for Gallery {
|
||||
}
|
||||
};
|
||||
if self.story.is_some() {
|
||||
return root.child(
|
||||
return self.root(cx).child(
|
||||
on_axis(div().id(("story", self.pass)))
|
||||
.size_full()
|
||||
.overflow_y_scroll()
|
||||
@@ -293,7 +292,12 @@ impl Render for Gallery {
|
||||
.child(div().p_6().child(body)),
|
||||
);
|
||||
}
|
||||
root.child(sidebar).child(
|
||||
let sidebar = self.sidebar(cx);
|
||||
let switcher = self.switcher(cx);
|
||||
let theme = cx.theme();
|
||||
let colors = &theme.colors;
|
||||
|
||||
self.root(cx).child(sidebar).child(
|
||||
on_axis(div().id(("page", self.pass)))
|
||||
.flex_1()
|
||||
.h_full()
|
||||
|
||||
+15
-6
@@ -163,20 +163,29 @@ pub fn blocked(text: impl Into<SharedString>, cx: &App) -> impl IntoElement {
|
||||
.child(div().flex_1().min_w_0().child(text.into()))
|
||||
}
|
||||
|
||||
/// Why a demo that takes files takes none on the web.
|
||||
pub const NO_FILES: &str = "A browser hands gpui no files: on the web the file dialog fails and dropped files never arrive, so nothing is taken here.";
|
||||
|
||||
/// What a browser cannot do here, and why: a note on the web, nothing natively.
|
||||
pub fn web_note(text: &'static str, cx: &App) -> Option<AnyElement> {
|
||||
cfg!(target_family = "wasm").then(|| blocked(text, cx).into_any_element())
|
||||
}
|
||||
|
||||
/// A button that opens a window of its own; a browser page is one window, so there a note stands in.
|
||||
/// A demo a browser cannot run: on the web its note stands in.
|
||||
pub fn native_only(element: impl IntoElement, note: &'static str, cx: &App) -> AnyElement {
|
||||
match web_note(note, cx) {
|
||||
Some(note) => note,
|
||||
None => element.into_any_element(),
|
||||
}
|
||||
}
|
||||
|
||||
/// A button that opens a window of its own, which a browser page cannot.
|
||||
pub fn own_window(button: impl IntoElement, cx: &App) -> AnyElement {
|
||||
match web_note(
|
||||
native_only(
|
||||
button,
|
||||
"A browser page is a single window: gpui opens no second window or popup on the web, so this one cannot open here.",
|
||||
cx,
|
||||
) {
|
||||
Some(note) => note,
|
||||
None => button.into_any_element(),
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/// A demo's state, kept across frames under `key`.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use std::{cell::RefCell, rc::Rc, sync::Arc};
|
||||
use std::{borrow::Cow, cell::RefCell, rc::Rc, sync::Arc};
|
||||
|
||||
use anyhow::{Context as _, Result, anyhow, bail};
|
||||
use ely_gpui_component::Assets;
|
||||
@@ -9,6 +9,9 @@ use web_sys::UrlSearchParams;
|
||||
|
||||
use crate::{Start, choose, launch, pages, shell::Choice, shell::Gallery};
|
||||
|
||||
/// The i18n page's Hebrew: gpui_web asks the browser for emoji and CJK alone.
|
||||
const HEBREW: &[u8] = include_bytes!("fonts/NotoSansHebrew-Regular.ttf");
|
||||
|
||||
thread_local! {
|
||||
/// The running app and its window, for the host page's calls.
|
||||
static HOST: RefCell<Option<(AsyncApp, WindowHandle<Gallery>)>> = const { RefCell::new(None) };
|
||||
@@ -95,6 +98,9 @@ pub fn start() {
|
||||
.with_http_client(http)
|
||||
.with_assets(Assets)
|
||||
.run(move |cx| {
|
||||
cx.text_system()
|
||||
.add_fonts(vec![Cow::Borrowed(HEBREW)])
|
||||
.expect("the gallery's Hebrew face registers");
|
||||
let window = launch(start, cx);
|
||||
HOST.with(|host| *host.borrow_mut() = Some((cx.to_async(), window)));
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user