gpui and gpui_platform now come from Zed's repo by git at 1a28cff, the code gpui-pre 0.3.7 republishes, so the gallery can later build for the browser. gpui takes stacker, as 0.2.2 always did, and gpui_platform takes font-kit, without which macOS draws no text; runtime_shaders moves to gpui_platform. The API moved: focus, blur and Tab steps take cx, Corner is Anchor, shaped lines paint with an alignment, defer_draw takes a content mask, the inspector registers a factory, async updates return their value, and wrapped lines are shared, not cloned. Updates through a window context go through the window, so a closed window still ends them as it did. Where the new gpui behaves differently, Ely keeps its old intent. Holds and reveals under a resting pointer survive typing through gpui's input-modality-independent hover; previews the keyboard also moves keep the default, and the calendar's leave ignores a key press. Enter reaches a button inside the code editor, since gpui now arms a key click on the press. The event logger skips a lone modifier. A video and an image grid keep their shape in a flex column under taffy 0.13, as a picture does. AGENTS.md records the new stack and the rules this port changes; the rest of the old gpui and taffy rules are re-tested in T44c.
192 lines
5.0 KiB
Rust
192 lines
5.0 KiB
Rust
use std::sync::Arc;
|
|
|
|
use gpui::{
|
|
App, Div, FontFeatures, FontWeight, Hsla, IntoElement, ParentElement, Refineable, RenderOnce,
|
|
SharedString, StyleRefinement, Styled, Window, div, relative,
|
|
};
|
|
|
|
use crate::theme::{ActiveTheme, Palette, TextSize};
|
|
|
|
/// Tabular numerals, so digits line up in columns.
|
|
pub fn tabular<E: Styled>(mut element: E) -> E {
|
|
let features = FontFeatures(Arc::new(vec![("tnum".into(), 1)]));
|
|
element.text_style().font_features = Some(features);
|
|
element
|
|
}
|
|
|
|
/// Each character drawn as itself, without ligatures: `==` stays two signs in encoded text and keys.
|
|
pub fn literal<E: Styled>(mut element: E) -> E {
|
|
let features = FontFeatures(Arc::new(vec![("calt".into(), 0), ("liga".into(), 0)]));
|
|
element.text_style().font_features = Some(features);
|
|
element
|
|
}
|
|
|
|
struct Spec {
|
|
size: TextSize,
|
|
weight: FontWeight,
|
|
color: fn(&Palette) -> Hsla,
|
|
leading: f32,
|
|
}
|
|
|
|
fn styled(text: SharedString, spec: Spec, style: &StyleRefinement, cx: &App) -> Div {
|
|
let theme = cx.theme();
|
|
let mut base = div()
|
|
.text_size(theme.text_size(spec.size))
|
|
.font_weight(spec.weight)
|
|
.text_color((spec.color)(&theme.colors))
|
|
.line_height(relative(spec.leading));
|
|
base.style().refine(style);
|
|
base.child(text)
|
|
}
|
|
|
|
macro_rules! text_kind {
|
|
($(#[$doc:meta])* $name:ident, $size:ident, $weight:ident, $color:ident, $leading:expr) => {
|
|
$(#[$doc])*
|
|
#[derive(IntoElement)]
|
|
pub struct $name {
|
|
text: SharedString,
|
|
style: StyleRefinement,
|
|
}
|
|
|
|
impl $name {
|
|
pub fn new(text: impl Into<SharedString>) -> Self {
|
|
Self { text: text.into(), style: StyleRefinement::default() }
|
|
}
|
|
}
|
|
|
|
impl Styled for $name {
|
|
fn style(&mut self) -> &mut StyleRefinement {
|
|
&mut self.style
|
|
}
|
|
}
|
|
|
|
impl RenderOnce for $name {
|
|
fn render(self, _: &mut Window, cx: &mut App) -> impl IntoElement {
|
|
let spec = Spec {
|
|
size: TextSize::$size,
|
|
weight: FontWeight::$weight,
|
|
color: |colors| colors.$color,
|
|
leading: $leading,
|
|
};
|
|
styled(self.text, spec, &self.style, cx)
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
text_kind!(Title, Xl, SEMIBOLD, fg, 1.3);
|
|
text_kind!(Subtitle, Lg, NORMAL, fg_muted, 1.45);
|
|
text_kind!(
|
|
/// Reading text. Loose leading.
|
|
Paragraph, Md, NORMAL, fg, 1.6
|
|
);
|
|
text_kind!(Label, Base, MEDIUM, fg, 1.4);
|
|
text_kind!(Caption, Sm, NORMAL, fg_muted, 1.45);
|
|
|
|
/// Small upper-case eyebrow above a heading.
|
|
#[derive(IntoElement)]
|
|
pub struct Overline {
|
|
text: SharedString,
|
|
style: StyleRefinement,
|
|
}
|
|
|
|
impl Overline {
|
|
pub fn new(text: impl Into<SharedString>) -> Self {
|
|
Self {
|
|
text: text.into(),
|
|
style: StyleRefinement::default(),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Styled for Overline {
|
|
fn style(&mut self) -> &mut StyleRefinement {
|
|
&mut self.style
|
|
}
|
|
}
|
|
|
|
impl RenderOnce for Overline {
|
|
fn render(self, _: &mut Window, cx: &mut App) -> impl IntoElement {
|
|
let spec = Spec {
|
|
size: TextSize::Xs,
|
|
weight: FontWeight::SEMIBOLD,
|
|
color: |colors| colors.fg_subtle,
|
|
leading: 1.4,
|
|
};
|
|
styled(self.text.to_uppercase().into(), spec, &self.style, cx)
|
|
}
|
|
}
|
|
|
|
/// H1 to H6.
|
|
#[derive(IntoElement)]
|
|
pub struct Heading {
|
|
level: u8,
|
|
text: SharedString,
|
|
style: StyleRefinement,
|
|
}
|
|
|
|
impl Heading {
|
|
/// Levels run 1 to 6; others panic.
|
|
pub fn new(level: u8, text: impl Into<SharedString>) -> Self {
|
|
assert!(
|
|
(1..=6).contains(&level),
|
|
"heading level {level} is not 1 to 6"
|
|
);
|
|
Self {
|
|
level,
|
|
text: text.into(),
|
|
style: StyleRefinement::default(),
|
|
}
|
|
}
|
|
|
|
pub fn h1(text: impl Into<SharedString>) -> Self {
|
|
Self::new(1, text)
|
|
}
|
|
|
|
pub fn h2(text: impl Into<SharedString>) -> Self {
|
|
Self::new(2, text)
|
|
}
|
|
|
|
pub fn h3(text: impl Into<SharedString>) -> Self {
|
|
Self::new(3, text)
|
|
}
|
|
|
|
pub fn h4(text: impl Into<SharedString>) -> Self {
|
|
Self::new(4, text)
|
|
}
|
|
|
|
pub fn h5(text: impl Into<SharedString>) -> Self {
|
|
Self::new(5, text)
|
|
}
|
|
|
|
pub fn h6(text: impl Into<SharedString>) -> Self {
|
|
Self::new(6, text)
|
|
}
|
|
}
|
|
|
|
impl Styled for Heading {
|
|
fn style(&mut self) -> &mut StyleRefinement {
|
|
&mut self.style
|
|
}
|
|
}
|
|
|
|
impl RenderOnce for Heading {
|
|
fn render(self, _: &mut Window, cx: &mut App) -> impl IntoElement {
|
|
let size = match self.level {
|
|
1 => TextSize::Display,
|
|
2 => TextSize::Xxl,
|
|
3 => TextSize::Xl,
|
|
4 => TextSize::Lg,
|
|
5 => TextSize::Md,
|
|
_ => TextSize::Base,
|
|
};
|
|
let spec = Spec {
|
|
size,
|
|
weight: FontWeight::SEMIBOLD,
|
|
color: |colors| colors.fg,
|
|
leading: 1.25,
|
|
};
|
|
styled(self.text, spec, &self.style, cx)
|
|
}
|
|
}
|