Merge branch 'main' into search2

This commit is contained in:
Piotr Osiewicz 2023-11-15 12:54:26 +01:00
commit b11bfa8821
163 changed files with 20705 additions and 13985 deletions

View file

@ -1,11 +1,9 @@
use std::sync::Arc;
use gpui::{div, DefiniteLength, Hsla, MouseButton, WindowContext};
use gpui::{div, DefiniteLength, Hsla, MouseButton, StatefulInteractiveComponent, WindowContext};
use crate::{
h_stack, prelude::*, Icon, IconButton, IconColor, IconElement, Label, LabelColor,
LineHeightStyle,
};
use crate::prelude::*;
use crate::{h_stack, Icon, IconButton, IconElement, Label, LineHeightStyle, TextColor};
/// Provides the flexibility to use either a standard
/// button or an icon button in a given context.
@ -87,6 +85,7 @@ pub struct Button<V: 'static> {
label: SharedString,
variant: ButtonVariant,
width: Option<DefiniteLength>,
color: Option<TextColor>,
}
impl<V: 'static> Button<V> {
@ -99,6 +98,7 @@ impl<V: 'static> Button<V> {
label: label.into(),
variant: Default::default(),
width: Default::default(),
color: None,
}
}
@ -139,34 +139,37 @@ impl<V: 'static> Button<V> {
self
}
fn label_color(&self) -> LabelColor {
pub fn color(mut self, color: Option<TextColor>) -> Self {
self.color = color;
self
}
pub fn label_color(&self, color: Option<TextColor>) -> TextColor {
if self.disabled {
LabelColor::Disabled
TextColor::Disabled
} else if let Some(color) = color {
color
} else {
Default::default()
}
}
fn icon_color(&self) -> IconColor {
if self.disabled {
IconColor::Disabled
} else {
Default::default()
}
}
fn render_label(&self) -> Label {
fn render_label(&self, color: TextColor) -> Label {
Label::new(self.label.clone())
.color(self.label_color())
.color(color)
.line_height_style(LineHeightStyle::UILabel)
}
fn render_icon(&self, icon_color: IconColor) -> Option<IconElement> {
fn render_icon(&self, icon_color: TextColor) -> Option<IconElement> {
self.icon.map(|i| IconElement::new(i).color(icon_color))
}
pub fn render(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
let icon_color = self.icon_color();
let (icon_color, label_color) = match (self.disabled, self.color) {
(true, _) => (TextColor::Disabled, TextColor::Disabled),
(_, None) => (TextColor::Default, TextColor::Default),
(_, Some(color)) => (TextColor::from(color), color),
};
let mut button = h_stack()
.id(SharedString::from(format!("{}", self.label)))
@ -182,16 +185,16 @@ impl<V: 'static> Button<V> {
(Some(_), Some(IconPosition::Left)) => {
button = button
.gap_1()
.child(self.render_label())
.child(self.render_label(label_color))
.children(self.render_icon(icon_color))
}
(Some(_), Some(IconPosition::Right)) => {
button = button
.gap_1()
.children(self.render_icon(icon_color))
.child(self.render_label())
.child(self.render_label(label_color))
}
(_, _) => button = button.child(self.render_label()),
(_, _) => button = button.child(self.render_label(label_color)),
}
if let Some(width) = self.width {
@ -235,7 +238,7 @@ pub use stories::*;
#[cfg(feature = "stories")]
mod stories {
use super::*;
use crate::{h_stack, v_stack, LabelColor, Story};
use crate::{h_stack, v_stack, Story, TextColor};
use gpui::{rems, Div, Render};
use strum::IntoEnumIterator;
@ -260,7 +263,7 @@ mod stories {
v_stack()
.gap_1()
.child(
Label::new(state.to_string()).color(LabelColor::Muted),
Label::new(state.to_string()).color(TextColor::Muted),
)
.child(
Button::new("Label").variant(ButtonVariant::Ghost), // .state(state),
@ -271,7 +274,7 @@ mod stories {
v_stack()
.gap_1()
.child(
Label::new(state.to_string()).color(LabelColor::Muted),
Label::new(state.to_string()).color(TextColor::Muted),
)
.child(
Button::new("Label")
@ -285,7 +288,7 @@ mod stories {
v_stack()
.gap_1()
.child(
Label::new(state.to_string()).color(LabelColor::Muted),
Label::new(state.to_string()).color(TextColor::Muted),
)
.child(
Button::new("Label")
@ -302,7 +305,7 @@ mod stories {
v_stack()
.gap_1()
.child(
Label::new(state.to_string()).color(LabelColor::Muted),
Label::new(state.to_string()).color(TextColor::Muted),
)
.child(
Button::new("Label").variant(ButtonVariant::Filled), // .state(state),
@ -313,7 +316,7 @@ mod stories {
v_stack()
.gap_1()
.child(
Label::new(state.to_string()).color(LabelColor::Muted),
Label::new(state.to_string()).color(TextColor::Muted),
)
.child(
Button::new("Label")
@ -327,7 +330,7 @@ mod stories {
v_stack()
.gap_1()
.child(
Label::new(state.to_string()).color(LabelColor::Muted),
Label::new(state.to_string()).color(TextColor::Muted),
)
.child(
Button::new("Label")
@ -344,7 +347,7 @@ mod stories {
v_stack()
.gap_1()
.child(
Label::new(state.to_string()).color(LabelColor::Muted),
Label::new(state.to_string()).color(TextColor::Muted),
)
.child(
Button::new("Label")
@ -358,7 +361,7 @@ mod stories {
v_stack()
.gap_1()
.child(
Label::new(state.to_string()).color(LabelColor::Muted),
Label::new(state.to_string()).color(TextColor::Muted),
)
.child(
Button::new("Label")
@ -374,7 +377,7 @@ mod stories {
v_stack()
.gap_1()
.child(
Label::new(state.to_string()).color(LabelColor::Muted),
Label::new(state.to_string()).color(TextColor::Muted),
)
.child(
Button::new("Label")

View file

@ -1,12 +1,8 @@
use gpui::{div, prelude::*, Component, ElementId, Styled, ViewContext};
use std::sync::Arc;
use gpui::{
div, Component, ElementId, ParentElement, StatefulInteractive, StatelessInteractive, Styled,
ViewContext,
};
use theme2::ActiveTheme;
use crate::{Icon, IconColor, IconElement, Selection};
use crate::{Icon, IconElement, Selection, TextColor};
pub type CheckHandler<V> = Arc<dyn Fn(Selection, &mut V, &mut ViewContext<V>) + Send + Sync>;
@ -58,9 +54,9 @@ impl<V: 'static> Checkbox<V> {
.color(
// If the checkbox is disabled we change the color of the icon.
if self.disabled {
IconColor::Disabled
TextColor::Disabled
} else {
IconColor::Selected
TextColor::Selected
},
),
)
@ -73,9 +69,9 @@ impl<V: 'static> Checkbox<V> {
.color(
// If the checkbox is disabled we change the color of the icon.
if self.disabled {
IconColor::Disabled
TextColor::Disabled
} else {
IconColor::Selected
TextColor::Selected
},
),
)

View file

@ -23,6 +23,6 @@ pub fn elevated_surface<V: 'static>(level: ElevationIndex, cx: &mut ViewContext<
.shadow(level.shadow())
}
pub fn modal<V>(cx: &mut ViewContext<V>) -> Div<V> {
pub fn modal<V: 'static>(cx: &mut ViewContext<V>) -> Div<V> {
elevated_surface(ElevationIndex::ModalSurface, cx)
}

View file

@ -1,4 +1,4 @@
use gpui::{rems, svg, Hsla};
use gpui::{rems, svg};
use strum::EnumIter;
use crate::prelude::*;
@ -10,38 +10,6 @@ pub enum IconSize {
Medium,
}
#[derive(Default, PartialEq, Copy, Clone)]
pub enum IconColor {
#[default]
Default,
Muted,
Disabled,
Placeholder,
Accent,
Error,
Warning,
Success,
Info,
Selected,
}
impl IconColor {
pub fn color(self, cx: &WindowContext) -> Hsla {
match self {
IconColor::Default => cx.theme().colors().icon,
IconColor::Muted => cx.theme().colors().icon_muted,
IconColor::Disabled => cx.theme().colors().icon_disabled,
IconColor::Placeholder => cx.theme().colors().icon_placeholder,
IconColor::Accent => cx.theme().colors().icon_accent,
IconColor::Error => cx.theme().status().error,
IconColor::Warning => cx.theme().status().warning,
IconColor::Success => cx.theme().status().success,
IconColor::Info => cx.theme().status().info,
IconColor::Selected => cx.theme().colors().icon_accent,
}
}
}
#[derive(Debug, PartialEq, Copy, Clone, EnumIter)]
pub enum Icon {
Ai,
@ -165,21 +133,29 @@ impl Icon {
#[derive(Component)]
pub struct IconElement {
icon: Icon,
color: IconColor,
path: SharedString,
color: TextColor,
size: IconSize,
}
impl IconElement {
pub fn new(icon: Icon) -> Self {
Self {
icon,
color: IconColor::default(),
path: icon.path().into(),
color: TextColor::default(),
size: IconSize::default(),
}
}
pub fn color(mut self, color: IconColor) -> Self {
pub fn from_path(path: impl Into<SharedString>) -> Self {
Self {
path: path.into(),
color: TextColor::default(),
size: IconSize::default(),
}
}
pub fn color(mut self, color: TextColor) -> Self {
self.color = color;
self
}
@ -198,7 +174,7 @@ impl IconElement {
svg()
.size(svg_size)
.flex_none()
.path(self.icon.path())
.path(self.path)
.text_color(self.color.color(cx))
}
}

View file

@ -1,10 +1,7 @@
use crate::{h_stack, prelude::*, ClickHandler, Icon, IconElement, TextTooltip};
use gpui::{prelude::*, MouseButton, VisualContext};
use std::sync::Arc;
use gpui::{rems, MouseButton};
use crate::{h_stack, prelude::*};
use crate::{ClickHandler, Icon, IconColor, IconElement};
struct IconButtonHandlers<V: 'static> {
click: Option<ClickHandler<V>>,
}
@ -19,9 +16,10 @@ impl<V: 'static> Default for IconButtonHandlers<V> {
pub struct IconButton<V: 'static> {
id: ElementId,
icon: Icon,
color: IconColor,
color: TextColor,
variant: ButtonVariant,
state: InteractionState,
tooltip: Option<SharedString>,
handlers: IconButtonHandlers<V>,
}
@ -30,9 +28,10 @@ impl<V: 'static> IconButton<V> {
Self {
id: id.into(),
icon,
color: IconColor::default(),
color: TextColor::default(),
variant: ButtonVariant::default(),
state: InteractionState::default(),
tooltip: None,
handlers: IconButtonHandlers::default(),
}
}
@ -42,7 +41,7 @@ impl<V: 'static> IconButton<V> {
self
}
pub fn color(mut self, color: IconColor) -> Self {
pub fn color(mut self, color: TextColor) -> Self {
self.color = color;
self
}
@ -57,6 +56,11 @@ impl<V: 'static> IconButton<V> {
self
}
pub fn tooltip(mut self, tooltip: impl Into<SharedString>) -> Self {
self.tooltip = Some(tooltip.into());
self
}
pub fn on_click(
mut self,
handler: impl 'static + Fn(&mut V, &mut ViewContext<V>) + Send + Sync,
@ -67,7 +71,7 @@ impl<V: 'static> IconButton<V> {
fn render(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
let icon_color = match (self.state, self.color) {
(InteractionState::Disabled, _) => IconColor::Disabled,
(InteractionState::Disabled, _) => TextColor::Disabled,
_ => self.color,
};
@ -88,9 +92,7 @@ impl<V: 'static> IconButton<V> {
.id(self.id.clone())
.justify_center()
.rounded_md()
// todo!("Where do these numbers come from?")
.py(rems(0.21875))
.px(rems(0.375))
.p_1()
.bg(bg_color)
.hover(|style| style.bg(bg_hover_color))
.active(|style| style.bg(bg_active_color))
@ -103,6 +105,11 @@ impl<V: 'static> IconButton<V> {
});
}
if let Some(tooltip) = self.tooltip.clone() {
button =
button.tooltip(move |_, cx| cx.build_view(|cx| TextTooltip::new(tooltip.clone())));
}
button
}
}

View file

@ -1,6 +1,5 @@
use crate::prelude::*;
use crate::Label;
use crate::LabelColor;
use crate::{prelude::*, Label};
use gpui::prelude::*;
#[derive(Default, PartialEq)]
pub enum InputVariant {
@ -71,15 +70,15 @@ impl Input {
};
let placeholder_label = Label::new(self.placeholder.clone()).color(if self.disabled {
LabelColor::Disabled
TextColor::Disabled
} else {
LabelColor::Placeholder
TextColor::Placeholder
});
let label = Label::new(self.value.clone()).color(if self.disabled {
LabelColor::Disabled
TextColor::Disabled
} else {
LabelColor::Default
TextColor::Default
});
div()

View file

@ -1,50 +1,43 @@
use std::collections::HashSet;
use strum::{EnumIter, IntoEnumIterator};
use gpui::Action;
use strum::EnumIter;
use crate::prelude::*;
#[derive(Component)]
pub struct Keybinding {
#[derive(Component, Clone)]
pub struct KeyBinding {
/// A keybinding consists of a key and a set of modifier keys.
/// More then one keybinding produces a chord.
///
/// This should always contain at least one element.
keybinding: Vec<(String, ModifierKeys)>,
key_binding: gpui::KeyBinding,
}
impl Keybinding {
pub fn new(key: String, modifiers: ModifierKeys) -> Self {
Self {
keybinding: vec![(key, modifiers)],
}
impl KeyBinding {
pub fn for_action(action: &dyn Action, cx: &mut WindowContext) -> Option<Self> {
// todo! this last is arbitrary, we want to prefer users key bindings over defaults,
// and vim over normal (in vim mode), etc.
let key_binding = cx.bindings_for_action(action).last().cloned()?;
Some(Self::new(key_binding))
}
pub fn new_chord(
first_note: (String, ModifierKeys),
second_note: (String, ModifierKeys),
) -> Self {
Self {
keybinding: vec![first_note, second_note],
}
pub fn new(key_binding: gpui::KeyBinding) -> Self {
Self { key_binding }
}
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
div()
.flex()
.gap_2()
.children(self.keybinding.iter().map(|(key, modifiers)| {
.children(self.key_binding.keystrokes().iter().map(|keystroke| {
div()
.flex()
.gap_1()
.children(ModifierKey::iter().filter_map(|modifier| {
if modifiers.0.contains(&modifier) {
Some(Key::new(modifier.glyph().to_string()))
} else {
None
}
}))
.child(Key::new(key.clone()))
.when(keystroke.modifiers.function, |el| el.child(Key::new("fn")))
.when(keystroke.modifiers.control, |el| el.child(Key::new("^")))
.when(keystroke.modifiers.alt, |el| el.child(Key::new("")))
.when(keystroke.modifiers.command, |el| el.child(Key::new("")))
.when(keystroke.modifiers.shift, |el| el.child(Key::new("")))
.child(Key::new(keystroke.key.clone()))
}))
}
}
@ -81,76 +74,6 @@ pub enum ModifierKey {
Shift,
}
impl ModifierKey {
/// Returns the glyph for the [`ModifierKey`].
pub fn glyph(&self) -> char {
match self {
Self::Control => '^',
Self::Alt => '⌥',
Self::Command => '⌘',
Self::Shift => '⇧',
}
}
}
#[derive(Clone)]
pub struct ModifierKeys(HashSet<ModifierKey>);
impl ModifierKeys {
pub fn new() -> Self {
Self(HashSet::new())
}
pub fn all() -> Self {
Self(HashSet::from_iter(ModifierKey::iter()))
}
pub fn add(mut self, modifier: ModifierKey) -> Self {
self.0.insert(modifier);
self
}
pub fn control(mut self, control: bool) -> Self {
if control {
self.0.insert(ModifierKey::Control);
} else {
self.0.remove(&ModifierKey::Control);
}
self
}
pub fn alt(mut self, alt: bool) -> Self {
if alt {
self.0.insert(ModifierKey::Alt);
} else {
self.0.remove(&ModifierKey::Alt);
}
self
}
pub fn command(mut self, command: bool) -> Self {
if command {
self.0.insert(ModifierKey::Command);
} else {
self.0.remove(&ModifierKey::Command);
}
self
}
pub fn shift(mut self, shift: bool) -> Self {
if shift {
self.0.insert(ModifierKey::Shift);
} else {
self.0.remove(&ModifierKey::Shift);
}
self
}
}
#[cfg(feature = "stories")]
pub use stories::*;
@ -158,29 +81,38 @@ pub use stories::*;
mod stories {
use super::*;
use crate::Story;
use gpui::{Div, Render};
use gpui::{action, Div, Render};
use itertools::Itertools;
pub struct KeybindingStory;
#[action]
struct NoAction {}
pub fn binding(key: &str) -> gpui::KeyBinding {
gpui::KeyBinding::new(key, NoAction {}, None)
}
impl Render for KeybindingStory {
type Element = Div<Self>;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
let all_modifier_permutations = ModifierKey::iter().permutations(2);
let all_modifier_permutations =
["ctrl", "alt", "cmd", "shift"].into_iter().permutations(2);
Story::container(cx)
.child(Story::title_for::<_, Keybinding>(cx))
.child(Story::title_for::<_, KeyBinding>(cx))
.child(Story::label(cx, "Single Key"))
.child(Keybinding::new("Z".to_string(), ModifierKeys::new()))
.child(KeyBinding::new(binding("Z")))
.child(Story::label(cx, "Single Key with Modifier"))
.child(
div()
.flex()
.gap_3()
.children(ModifierKey::iter().map(|modifier| {
Keybinding::new("C".to_string(), ModifierKeys::new().add(modifier))
})),
.child(KeyBinding::new(binding("ctrl-c")))
.child(KeyBinding::new(binding("alt-c")))
.child(KeyBinding::new(binding("cmd-c")))
.child(KeyBinding::new(binding("shift-c"))),
)
.child(Story::label(cx, "Single Key with Modifier (Permuted)"))
.child(
@ -194,29 +126,18 @@ mod stories {
.gap_4()
.py_3()
.children(chunk.map(|permutation| {
let mut modifiers = ModifierKeys::new();
for modifier in permutation {
modifiers = modifiers.add(modifier);
}
Keybinding::new("X".to_string(), modifiers)
KeyBinding::new(binding(&*(permutation.join("-") + "-x")))
}))
}),
),
)
.child(Story::label(cx, "Single Key with All Modifiers"))
.child(Keybinding::new("Z".to_string(), ModifierKeys::all()))
.child(KeyBinding::new(binding("ctrl-alt-cmd-shift-z")))
.child(Story::label(cx, "Chord"))
.child(Keybinding::new_chord(
("A".to_string(), ModifierKeys::new()),
("Z".to_string(), ModifierKeys::new()),
))
.child(KeyBinding::new(binding("a z")))
.child(Story::label(cx, "Chord with Modifier"))
.child(Keybinding::new_chord(
("A".to_string(), ModifierKeys::new().control(true)),
("Z".to_string(), ModifierKeys::new().shift(true)),
))
.child(KeyBinding::new(binding("ctrl-a shift-z")))
.child(KeyBinding::new(binding("fn-s")))
}
}
}

View file

@ -1,35 +1,53 @@
use gpui::{relative, Hsla, WindowContext};
use smallvec::SmallVec;
use gpui::{relative, Hsla, Text, TextRun, WindowContext};
use crate::prelude::*;
use crate::styled_ext::StyledExt;
#[derive(Default, PartialEq, Copy, Clone)]
pub enum LabelColor {
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Default)]
pub enum LabelSize {
#[default]
Default,
Muted,
Created,
Modified,
Deleted,
Disabled,
Hidden,
Placeholder,
Accent,
Small,
}
impl LabelColor {
pub fn hsla(&self, cx: &WindowContext) -> Hsla {
#[derive(Default, PartialEq, Copy, Clone)]
pub enum TextColor {
#[default]
Default,
Accent,
Created,
Deleted,
Disabled,
Error,
Hidden,
Info,
Modified,
Muted,
Placeholder,
Player(u32),
Selected,
Success,
Warning,
}
impl TextColor {
pub fn color(&self, cx: &WindowContext) -> Hsla {
match self {
Self::Default => cx.theme().colors().text,
Self::Muted => cx.theme().colors().text_muted,
Self::Created => cx.theme().status().created,
Self::Modified => cx.theme().status().modified,
Self::Deleted => cx.theme().status().deleted,
Self::Disabled => cx.theme().colors().text_disabled,
Self::Hidden => cx.theme().status().hidden,
Self::Placeholder => cx.theme().colors().text_placeholder,
Self::Accent => cx.theme().colors().text_accent,
TextColor::Default => cx.theme().colors().text,
TextColor::Muted => cx.theme().colors().text_muted,
TextColor::Created => cx.theme().status().created,
TextColor::Modified => cx.theme().status().modified,
TextColor::Deleted => cx.theme().status().deleted,
TextColor::Disabled => cx.theme().colors().text_disabled,
TextColor::Hidden => cx.theme().status().hidden,
TextColor::Info => cx.theme().status().info,
TextColor::Placeholder => cx.theme().colors().text_placeholder,
TextColor::Accent => cx.theme().colors().text_accent,
TextColor::Player(i) => cx.theme().styles.player.0[i.clone() as usize].cursor,
TextColor::Error => cx.theme().status().error,
TextColor::Selected => cx.theme().colors().text_accent,
TextColor::Success => cx.theme().status().success,
TextColor::Warning => cx.theme().status().warning,
}
}
}
@ -45,8 +63,9 @@ pub enum LineHeightStyle {
#[derive(Component)]
pub struct Label {
label: SharedString,
size: LabelSize,
line_height_style: LineHeightStyle,
color: LabelColor,
color: TextColor,
strikethrough: bool,
}
@ -54,13 +73,19 @@ impl Label {
pub fn new(label: impl Into<SharedString>) -> Self {
Self {
label: label.into(),
size: LabelSize::Default,
line_height_style: LineHeightStyle::default(),
color: LabelColor::Default,
color: TextColor::Default,
strikethrough: false,
}
}
pub fn color(mut self, color: LabelColor) -> Self {
pub fn size(mut self, size: LabelSize) -> Self {
self.size = size;
self
}
pub fn color(mut self, color: TextColor) -> Self {
self.color = color;
self
}
@ -84,14 +109,17 @@ impl Label {
.top_1_2()
.w_full()
.h_px()
.bg(LabelColor::Hidden.hsla(cx)),
.bg(TextColor::Hidden.color(cx)),
)
})
.text_ui()
.map(|this| match self.size {
LabelSize::Default => this.text_ui(),
LabelSize::Small => this.text_ui_sm(),
})
.when(self.line_height_style == LineHeightStyle::UILabel, |this| {
this.line_height(relative(1.))
})
.text_color(self.color.hsla(cx))
.text_color(self.color.color(cx))
.child(self.label.clone())
}
}
@ -99,22 +127,31 @@ impl Label {
#[derive(Component)]
pub struct HighlightedLabel {
label: SharedString,
color: LabelColor,
size: LabelSize,
color: TextColor,
highlight_indices: Vec<usize>,
strikethrough: bool,
}
impl HighlightedLabel {
/// shows a label with the given characters highlighted.
/// characters are identified by utf8 byte position.
pub fn new(label: impl Into<SharedString>, highlight_indices: Vec<usize>) -> Self {
Self {
label: label.into(),
color: LabelColor::Default,
size: LabelSize::Default,
color: TextColor::Default,
highlight_indices,
strikethrough: false,
}
}
pub fn color(mut self, color: LabelColor) -> Self {
pub fn size(mut self, size: LabelSize) -> Self {
self.size = size;
self
}
pub fn color(mut self, color: TextColor) -> Self {
self.color = color;
self
}
@ -126,27 +163,26 @@ impl HighlightedLabel {
fn render<V: 'static>(self, _view: &mut V, cx: &mut ViewContext<V>) -> impl Component<V> {
let highlight_color = cx.theme().colors().text_accent;
let mut text_style = cx.text_style().clone();
let mut highlight_indices = self.highlight_indices.iter().copied().peekable();
let mut runs: SmallVec<[Run; 8]> = SmallVec::new();
let mut runs: Vec<TextRun> = Vec::new();
for (char_ix, char) in self.label.char_indices() {
let mut color = self.color.hsla(cx);
let mut color = self.color.color(cx);
if let Some(highlight_ix) = highlight_indices.peek() {
if char_ix == *highlight_ix {
color = highlight_color;
highlight_indices.next();
}
}
let last_run = runs.last_mut();
let start_new_run = if let Some(last_run) = last_run {
if color == last_run.color {
last_run.text.push(char);
last_run.len += char.len_utf8();
false
} else {
true
@ -156,10 +192,8 @@ impl HighlightedLabel {
};
if start_new_run {
runs.push(Run {
text: char.to_string(),
color,
});
text_style.color = color;
runs.push(text_style.to_run(char.len_utf8()))
}
}
@ -173,13 +207,14 @@ impl HighlightedLabel {
.my_auto()
.w_full()
.h_px()
.bg(LabelColor::Hidden.hsla(cx)),
.bg(TextColor::Hidden.color(cx)),
)
})
.children(
runs.into_iter()
.map(|run| div().text_color(run.color).child(run.text)),
)
.map(|this| match self.size {
LabelSize::Default => this.text_ui(),
LabelSize::Small => this.text_ui_sm(),
})
.child(Text::styled(self.label, runs))
}
}
@ -213,6 +248,10 @@ mod stories {
"Hello, world!",
vec![0, 1, 2, 7, 8, 12],
))
.child(HighlightedLabel::new(
"Héllo, world!",
vec![0, 1, 3, 8, 9, 13],
))
}
}
}

View file

@ -1,11 +1,11 @@
use gpui::div;
use crate::prelude::*;
use crate::settings::user_settings;
use crate::{
disclosure_control, h_stack, v_stack, Avatar, Icon, IconColor, IconElement, IconSize, Label,
LabelColor, Toggle,
disclosure_control, h_stack, v_stack, Avatar, GraphicSlot, Icon, IconElement, IconSize, Label,
TextColor, Toggle,
};
use crate::{prelude::*, GraphicSlot};
#[derive(Clone, Copy, Default, Debug, PartialEq)]
pub enum ListItemVariant {
@ -68,7 +68,7 @@ impl ListHeader {
.items_center()
.children(icons.into_iter().map(|i| {
IconElement::new(i)
.color(IconColor::Muted)
.color(TextColor::Muted)
.size(IconSize::Small)
})),
),
@ -106,10 +106,10 @@ impl ListHeader {
.items_center()
.children(self.left_icon.map(|i| {
IconElement::new(i)
.color(IconColor::Muted)
.color(TextColor::Muted)
.size(IconSize::Small)
}))
.child(Label::new(self.label.clone()).color(LabelColor::Muted)),
.child(Label::new(self.label.clone()).color(TextColor::Muted)),
)
.child(disclosure_control),
)
@ -157,10 +157,10 @@ impl ListSubHeader {
.items_center()
.children(self.left_icon.map(|i| {
IconElement::new(i)
.color(IconColor::Muted)
.color(TextColor::Muted)
.size(IconSize::Small)
}))
.child(Label::new(self.label.clone()).color(LabelColor::Muted)),
.child(Label::new(self.label.clone()).color(TextColor::Muted)),
),
)
}
@ -291,7 +291,7 @@ impl ListEntry {
h_stack().child(
IconElement::new(i)
.size(IconSize::Small)
.color(IconColor::Muted),
.color(TextColor::Muted),
),
),
Some(GraphicSlot::Avatar(src)) => Some(h_stack().child(Avatar::new(src))),
@ -394,14 +394,14 @@ impl List {
(false, _) => div().children(self.items),
(true, Toggle::Toggled(false)) => div(),
(true, _) => {
div().child(Label::new(self.empty_message.clone()).color(LabelColor::Muted))
div().child(Label::new(self.empty_message.clone()).color(TextColor::Muted))
}
};
v_stack()
.w_full()
.py_1()
.children(self.header.map(|header| header))
.children(self.header)
.child(list_content)
}
}

View file

@ -74,7 +74,7 @@ impl<V: 'static> Modal<V> {
}
}
impl<V: 'static> ParentElement<V> for Modal<V> {
impl<V: 'static> ParentComponent<V> for Modal<V> {
fn children_mut(&mut self) -> &mut SmallVec<[AnyElement<V>; 2]> {
&mut self.children
}

View file

@ -1,5 +1,5 @@
use crate::prelude::*;
use crate::{h_stack, v_stack, Keybinding, Label, LabelColor};
use crate::{h_stack, prelude::*, v_stack, KeyBinding, Label};
use gpui::prelude::*;
#[derive(Component)]
pub struct Palette {
@ -54,7 +54,7 @@ impl Palette {
v_stack()
.gap_px()
.child(v_stack().py_0p5().px_1().child(div().px_2().py_0p5().child(
Label::new(self.input_placeholder.clone()).color(LabelColor::Placeholder),
Label::new(self.input_placeholder.clone()).color(TextColor::Placeholder),
)))
.child(
div()
@ -75,7 +75,7 @@ impl Palette {
Some(
h_stack().justify_between().px_2().py_1().child(
Label::new(self.empty_string.clone())
.color(LabelColor::Muted),
.color(TextColor::Muted),
),
)
} else {
@ -108,7 +108,7 @@ impl Palette {
pub struct PaletteItem {
pub label: SharedString,
pub sublabel: Option<SharedString>,
pub keybinding: Option<Keybinding>,
pub key_binding: Option<KeyBinding>,
}
impl PaletteItem {
@ -116,7 +116,7 @@ impl PaletteItem {
Self {
label: label.into(),
sublabel: None,
keybinding: None,
key_binding: None,
}
}
@ -130,11 +130,8 @@ impl PaletteItem {
self
}
pub fn keybinding<K>(mut self, keybinding: K) -> Self
where
K: Into<Option<Keybinding>>,
{
self.keybinding = keybinding.into();
pub fn key_binding(mut self, key_binding: impl Into<Option<KeyBinding>>) -> Self {
self.key_binding = key_binding.into();
self
}
@ -149,7 +146,7 @@ impl PaletteItem {
.child(Label::new(self.label.clone()))
.children(self.sublabel.clone().map(|sublabel| Label::new(sublabel))),
)
.children(self.keybinding)
.children(self.key_binding)
}
}
@ -161,7 +158,7 @@ pub use stories::*;
mod stories {
use gpui::{Div, Render};
use crate::{ModifierKeys, Story};
use crate::{binding, Story};
use super::*;
@ -181,46 +178,24 @@ mod stories {
Palette::new("palette-2")
.placeholder("Execute a command...")
.items(vec![
PaletteItem::new("theme selector: toggle").keybinding(
Keybinding::new_chord(
("k".to_string(), ModifierKeys::new().command(true)),
("t".to_string(), ModifierKeys::new().command(true)),
),
),
PaletteItem::new("assistant: inline assist").keybinding(
Keybinding::new(
"enter".to_string(),
ModifierKeys::new().command(true),
),
),
PaletteItem::new("assistant: quote selection").keybinding(
Keybinding::new(
">".to_string(),
ModifierKeys::new().command(true),
),
),
PaletteItem::new("assistant: toggle focus").keybinding(
Keybinding::new(
"?".to_string(),
ModifierKeys::new().command(true),
),
),
PaletteItem::new("theme selector: toggle")
.key_binding(KeyBinding::new(binding("cmd-k cmd-t"))),
PaletteItem::new("assistant: inline assist")
.key_binding(KeyBinding::new(binding("cmd-enter"))),
PaletteItem::new("assistant: quote selection")
.key_binding(KeyBinding::new(binding("cmd-<"))),
PaletteItem::new("assistant: toggle focus")
.key_binding(KeyBinding::new(binding("cmd-?"))),
PaletteItem::new("auto update: check"),
PaletteItem::new("auto update: view release notes"),
PaletteItem::new("branches: open recent").keybinding(
Keybinding::new(
"b".to_string(),
ModifierKeys::new().command(true).alt(true),
),
),
PaletteItem::new("branches: open recent")
.key_binding(KeyBinding::new(binding("cmd-alt-b"))),
PaletteItem::new("chat panel: toggle focus"),
PaletteItem::new("cli: install"),
PaletteItem::new("client: sign in"),
PaletteItem::new("client: sign out"),
PaletteItem::new("editor: cancel").keybinding(Keybinding::new(
"escape".to_string(),
ModifierKeys::new(),
)),
PaletteItem::new("editor: cancel")
.key_binding(KeyBinding::new(binding("escape"))),
]),
)
}

View file

@ -1,4 +1,4 @@
use gpui::{AbsoluteLength, AnyElement};
use gpui::{prelude::*, AbsoluteLength, AnyElement};
use smallvec::SmallVec;
use crate::prelude::*;
@ -113,7 +113,7 @@ impl<V: 'static> Panel<V> {
}
}
impl<V: 'static> ParentElement<V> for Panel<V> {
impl<V: 'static> ParentComponent<V> for Panel<V> {
fn children_mut(&mut self) -> &mut SmallVec<[AnyElement<V>; 2]> {
&mut self.children
}
@ -126,7 +126,7 @@ pub use stories::*;
mod stories {
use super::*;
use crate::{Label, Story};
use gpui::{Div, Render};
use gpui::{Div, InteractiveComponent, Render};
pub struct PanelStory;

View file

@ -1,6 +1,6 @@
use crate::prelude::*;
use crate::{Icon, IconColor, IconElement, Label, LabelColor};
use gpui::{red, Div, ElementId, Render, View, VisualContext};
use crate::{Icon, IconElement, Label, TextColor};
use gpui::{prelude::*, red, Div, ElementId, Render, View};
#[derive(Component, Clone)]
pub struct Tab {
@ -92,20 +92,18 @@ impl Tab {
let label = match (self.git_status, is_deleted) {
(_, true) | (GitStatus::Deleted, false) => Label::new(self.title.clone())
.color(LabelColor::Hidden)
.color(TextColor::Hidden)
.set_strikethrough(true),
(GitStatus::None, false) => Label::new(self.title.clone()),
(GitStatus::Created, false) => {
Label::new(self.title.clone()).color(LabelColor::Created)
}
(GitStatus::Created, false) => Label::new(self.title.clone()).color(TextColor::Created),
(GitStatus::Modified, false) => {
Label::new(self.title.clone()).color(LabelColor::Modified)
Label::new(self.title.clone()).color(TextColor::Modified)
}
(GitStatus::Renamed, false) => Label::new(self.title.clone()).color(LabelColor::Accent),
(GitStatus::Renamed, false) => Label::new(self.title.clone()).color(TextColor::Accent),
(GitStatus::Conflict, false) => Label::new(self.title.clone()),
};
let close_icon = || IconElement::new(Icon::Close).color(IconColor::Muted);
let close_icon = || IconElement::new(Icon::Close).color(TextColor::Muted);
let (tab_bg, tab_hover_bg, tab_active_bg) = match self.current {
false => (
@ -148,7 +146,7 @@ impl Tab {
.children(has_fs_conflict.then(|| {
IconElement::new(Icon::ExclamationTriangle)
.size(crate::IconSize::Small)
.color(IconColor::Warning)
.color(TextColor::Warning)
}))
.children(self.icon.map(IconElement::new))
.children(if self.close_side == IconSide::Left {

View file

@ -1,7 +1,6 @@
use gpui::AnyElement;
use smallvec::SmallVec;
use crate::prelude::*;
use gpui::{prelude::*, AnyElement};
use smallvec::SmallVec;
#[derive(Default, Debug, PartialEq, Eq, Clone, Copy)]
pub enum ToastOrigin {
@ -59,7 +58,7 @@ impl<V: 'static> Toast<V> {
}
}
impl<V: 'static> ParentElement<V> for Toast<V> {
impl<V: 'static> ParentComponent<V> for Toast<V> {
fn children_mut(&mut self) -> &mut SmallVec<[AnyElement<V>; 2]> {
&mut self.children
}

View file

@ -1,6 +1,6 @@
use gpui::{div, Component, ParentElement};
use gpui::{div, Component, ParentComponent};
use crate::{Icon, IconColor, IconElement, IconSize};
use crate::{Icon, IconElement, IconSize, TextColor};
/// Whether the entry is toggleable, and if so, whether it is currently toggled.
///
@ -49,12 +49,12 @@ pub fn disclosure_control<V: 'static>(toggle: Toggle) -> impl Component<V> {
(false, _) => div(),
(_, true) => div().child(
IconElement::new(Icon::ChevronDown)
.color(IconColor::Muted)
.color(TextColor::Muted)
.size(IconSize::Small),
),
(_, false) => div().child(
IconElement::new(Icon::ChevronRight)
.color(IconColor::Muted)
.color(TextColor::Muted)
.size(IconSize::Small),
),
}

View file

@ -1,14 +1,33 @@
use gpui::{div, Div, ParentElement, Render, SharedString, Styled, ViewContext};
use theme2::ActiveTheme;
use gpui::{Div, Render};
use settings2::Settings;
use theme2::{ActiveTheme, ThemeSettings};
use crate::prelude::*;
use crate::{h_stack, v_stack, KeyBinding, Label, LabelSize, StyledExt, TextColor};
#[derive(Clone, Debug)]
pub struct TextTooltip {
title: SharedString,
meta: Option<SharedString>,
key_binding: Option<KeyBinding>,
}
impl TextTooltip {
pub fn new(str: SharedString) -> Self {
Self { title: str }
pub fn new(title: impl Into<SharedString>) -> Self {
Self {
title: title.into(),
meta: None,
key_binding: None,
}
}
pub fn meta(mut self, meta: impl Into<SharedString>) -> Self {
self.meta = Some(meta.into());
self
}
pub fn key_binding(mut self, key_binding: impl Into<Option<KeyBinding>>) -> Self {
self.key_binding = key_binding.into();
self
}
}
@ -16,16 +35,27 @@ impl Render for TextTooltip {
type Element = Div<Self>;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
let theme = cx.theme();
div()
.bg(theme.colors().background)
.rounded_lg()
.border()
.font("Zed Sans")
.border_color(theme.colors().border)
.text_color(theme.colors().text)
.pl_2()
.pr_2()
.child(self.title.clone())
let ui_font = ThemeSettings::get_global(cx).ui_font.family.clone();
v_stack()
.elevation_2(cx)
.font(ui_font)
.text_ui_sm()
.text_color(cx.theme().colors().text)
.py_1()
.px_2()
.child(
h_stack()
.child(self.title.clone())
.when_some(self.key_binding.clone(), |this, key_binding| {
this.justify_between().child(key_binding)
}),
)
.when_some(self.meta.clone(), |this, meta| {
this.child(
Label::new(meta)
.size(LabelSize::Small)
.color(TextColor::Muted),
)
})
}
}

View file

@ -1,13 +1,13 @@
use gpui::rems;
use gpui::Rems;
pub use gpui::{
div, Component, Element, ElementId, ParentElement, SharedString, StatefulInteractive,
StatelessInteractive, Styled, ViewContext, WindowContext,
div, Component, Element, ElementId, InteractiveComponent, ParentComponent, SharedString,
Styled, ViewContext, WindowContext,
};
pub use crate::elevation::*;
pub use crate::ButtonVariant;
pub use crate::StyledExt;
pub use crate::{ButtonVariant, TextColor};
pub use theme2::ActiveTheme;
use gpui::Hsla;

View file

@ -7,12 +7,12 @@ use gpui::{AppContext, ViewContext};
use rand::Rng;
use theme2::ActiveTheme;
use crate::HighlightedText;
use crate::{binding, HighlightedText};
use crate::{
Buffer, BufferRow, BufferRows, Button, EditorPane, FileSystemStatus, GitStatus,
HighlightedLine, Icon, Keybinding, Label, LabelColor, ListEntry, ListEntrySize, Livestream,
MicStatus, ModifierKeys, Notification, PaletteItem, Player, PlayerCallStatus,
PlayerWithCallStatus, PublicPlayer, ScreenShareStatus, Symbol, Tab, Toggle, VideoStatus,
HighlightedLine, Icon, KeyBinding, Label, ListEntry, ListEntrySize, Livestream, MicStatus,
Notification, PaletteItem, Player, PlayerCallStatus, PlayerWithCallStatus, PublicPlayer,
ScreenShareStatus, Symbol, Tab, TextColor, Toggle, VideoStatus,
};
use crate::{ListItem, NotificationAction};
@ -490,20 +490,20 @@ pub fn static_project_panel_project_items() -> Vec<ListItem> {
ListEntry::new(Label::new(".config"))
.left_icon(Icon::Folder.into())
.indent_level(1),
ListEntry::new(Label::new(".git").color(LabelColor::Hidden))
ListEntry::new(Label::new(".git").color(TextColor::Hidden))
.left_icon(Icon::Folder.into())
.indent_level(1),
ListEntry::new(Label::new(".cargo"))
.left_icon(Icon::Folder.into())
.indent_level(1),
ListEntry::new(Label::new(".idea").color(LabelColor::Hidden))
ListEntry::new(Label::new(".idea").color(TextColor::Hidden))
.left_icon(Icon::Folder.into())
.indent_level(1),
ListEntry::new(Label::new("assets"))
.left_icon(Icon::Folder.into())
.indent_level(1)
.toggle(Toggle::Toggled(true)),
ListEntry::new(Label::new("cargo-target").color(LabelColor::Hidden))
ListEntry::new(Label::new("cargo-target").color(TextColor::Hidden))
.left_icon(Icon::Folder.into())
.indent_level(1),
ListEntry::new(Label::new("crates"))
@ -528,7 +528,7 @@ pub fn static_project_panel_project_items() -> Vec<ListItem> {
ListEntry::new(Label::new("call"))
.left_icon(Icon::Folder.into())
.indent_level(2),
ListEntry::new(Label::new("sqlez").color(LabelColor::Modified))
ListEntry::new(Label::new("sqlez").color(TextColor::Modified))
.left_icon(Icon::Folder.into())
.indent_level(2)
.toggle(Toggle::Toggled(false)),
@ -543,45 +543,45 @@ pub fn static_project_panel_project_items() -> Vec<ListItem> {
ListEntry::new(Label::new("derive_element.rs"))
.left_icon(Icon::FileRust.into())
.indent_level(4),
ListEntry::new(Label::new("storybook").color(LabelColor::Modified))
ListEntry::new(Label::new("storybook").color(TextColor::Modified))
.left_icon(Icon::FolderOpen.into())
.indent_level(1)
.toggle(Toggle::Toggled(true)),
ListEntry::new(Label::new("docs").color(LabelColor::Default))
ListEntry::new(Label::new("docs").color(TextColor::Default))
.left_icon(Icon::Folder.into())
.indent_level(2)
.toggle(Toggle::Toggled(true)),
ListEntry::new(Label::new("src").color(LabelColor::Modified))
ListEntry::new(Label::new("src").color(TextColor::Modified))
.left_icon(Icon::FolderOpen.into())
.indent_level(3)
.toggle(Toggle::Toggled(true)),
ListEntry::new(Label::new("ui").color(LabelColor::Modified))
ListEntry::new(Label::new("ui").color(TextColor::Modified))
.left_icon(Icon::FolderOpen.into())
.indent_level(4)
.toggle(Toggle::Toggled(true)),
ListEntry::new(Label::new("component").color(LabelColor::Created))
ListEntry::new(Label::new("component").color(TextColor::Created))
.left_icon(Icon::FolderOpen.into())
.indent_level(5)
.toggle(Toggle::Toggled(true)),
ListEntry::new(Label::new("facepile.rs").color(LabelColor::Default))
ListEntry::new(Label::new("facepile.rs").color(TextColor::Default))
.left_icon(Icon::FileRust.into())
.indent_level(6),
ListEntry::new(Label::new("follow_group.rs").color(LabelColor::Default))
ListEntry::new(Label::new("follow_group.rs").color(TextColor::Default))
.left_icon(Icon::FileRust.into())
.indent_level(6),
ListEntry::new(Label::new("list_item.rs").color(LabelColor::Created))
ListEntry::new(Label::new("list_item.rs").color(TextColor::Created))
.left_icon(Icon::FileRust.into())
.indent_level(6),
ListEntry::new(Label::new("tab.rs").color(LabelColor::Default))
ListEntry::new(Label::new("tab.rs").color(TextColor::Default))
.left_icon(Icon::FileRust.into())
.indent_level(6),
ListEntry::new(Label::new("target").color(LabelColor::Hidden))
ListEntry::new(Label::new("target").color(TextColor::Hidden))
.left_icon(Icon::Folder.into())
.indent_level(1),
ListEntry::new(Label::new(".dockerignore"))
.left_icon(Icon::FileGeneric.into())
.indent_level(1),
ListEntry::new(Label::new(".DS_Store").color(LabelColor::Hidden))
ListEntry::new(Label::new(".DS_Store").color(TextColor::Hidden))
.left_icon(Icon::FileGeneric.into())
.indent_level(1),
ListEntry::new(Label::new("Cargo.lock"))
@ -701,46 +701,16 @@ pub fn static_collab_panel_channels() -> Vec<ListItem> {
pub fn example_editor_actions() -> Vec<PaletteItem> {
vec![
PaletteItem::new("New File").keybinding(Keybinding::new(
"N".to_string(),
ModifierKeys::new().command(true),
)),
PaletteItem::new("Open File").keybinding(Keybinding::new(
"O".to_string(),
ModifierKeys::new().command(true),
)),
PaletteItem::new("Save File").keybinding(Keybinding::new(
"S".to_string(),
ModifierKeys::new().command(true),
)),
PaletteItem::new("Cut").keybinding(Keybinding::new(
"X".to_string(),
ModifierKeys::new().command(true),
)),
PaletteItem::new("Copy").keybinding(Keybinding::new(
"C".to_string(),
ModifierKeys::new().command(true),
)),
PaletteItem::new("Paste").keybinding(Keybinding::new(
"V".to_string(),
ModifierKeys::new().command(true),
)),
PaletteItem::new("Undo").keybinding(Keybinding::new(
"Z".to_string(),
ModifierKeys::new().command(true),
)),
PaletteItem::new("Redo").keybinding(Keybinding::new(
"Z".to_string(),
ModifierKeys::new().command(true).shift(true),
)),
PaletteItem::new("Find").keybinding(Keybinding::new(
"F".to_string(),
ModifierKeys::new().command(true),
)),
PaletteItem::new("Replace").keybinding(Keybinding::new(
"R".to_string(),
ModifierKeys::new().command(true),
)),
PaletteItem::new("New File").key_binding(KeyBinding::new(binding("cmd-n"))),
PaletteItem::new("Open File").key_binding(KeyBinding::new(binding("cmd-o"))),
PaletteItem::new("Save File").key_binding(KeyBinding::new(binding("cmd-s"))),
PaletteItem::new("Cut").key_binding(KeyBinding::new(binding("cmd-x"))),
PaletteItem::new("Copy").key_binding(KeyBinding::new(binding("cmd-c"))),
PaletteItem::new("Paste").key_binding(KeyBinding::new(binding("cmd-v"))),
PaletteItem::new("Undo").key_binding(KeyBinding::new(binding("cmd-z"))),
PaletteItem::new("Redo").key_binding(KeyBinding::new(binding("cmd-shift-z"))),
PaletteItem::new("Find").key_binding(KeyBinding::new(binding("cmd-f"))),
PaletteItem::new("Replace").key_binding(KeyBinding::new(binding("cmd-r"))),
PaletteItem::new("Jump to Line"),
PaletteItem::new("Select All"),
PaletteItem::new("Deselect All"),

View file

@ -1,4 +1,4 @@
use gpui::{Div, ElementFocus, ElementInteractivity, Styled, UniformList, ViewContext};
use gpui::{Styled, ViewContext};
use theme2::ActiveTheme;
use crate::{ElevationIndex, UITextSize};
@ -12,31 +12,22 @@ fn elevated<E: Styled, V: 'static>(this: E, cx: &mut ViewContext<V>, index: Elev
}
/// Extends [`Styled`](gpui::Styled) with Zed specific styling methods.
pub trait StyledExt: Styled {
pub trait StyledExt: Styled + Sized {
/// Horizontally stacks elements.
///
/// Sets `flex()`, `flex_row()`, `items_center()`
fn h_flex(self) -> Self
where
Self: Sized,
{
fn h_flex(self) -> Self {
self.flex().flex_row().items_center()
}
/// Vertically stacks elements.
///
/// Sets `flex()`, `flex_col()`
fn v_flex(self) -> Self
where
Self: Sized,
{
fn v_flex(self) -> Self {
self.flex().flex_col()
}
fn text_ui_size(self, size: UITextSize) -> Self
where
Self: Sized,
{
fn text_ui_size(self, size: UITextSize) -> Self {
let size = size.rems();
self.text_size(size)
@ -49,10 +40,7 @@ pub trait StyledExt: Styled {
/// Note: The absolute size of this text will change based on a user's `ui_scale` setting.
///
/// Use [`text_ui_sm`] for regular-sized text.
fn text_ui(self) -> Self
where
Self: Sized,
{
fn text_ui(self) -> Self {
let size = UITextSize::default().rems();
self.text_size(size)
@ -65,10 +53,7 @@ pub trait StyledExt: Styled {
/// Note: The absolute size of this text will change based on a user's `ui_scale` setting.
///
/// Use [`text_ui`] for regular-sized text.
fn text_ui_sm(self) -> Self
where
Self: Sized,
{
fn text_ui_sm(self) -> Self {
let size = UITextSize::Small.rems();
self.text_size(size)
@ -79,10 +64,7 @@ pub trait StyledExt: Styled {
/// Sets `bg()`, `rounded_lg()`, `border()`, `border_color()`, `shadow()`
///
/// Example Elements: Title Bar, Panel, Tab Bar, Editor
fn elevation_1<V: 'static>(self, cx: &mut ViewContext<V>) -> Self
where
Self: Styled + Sized,
{
fn elevation_1<V: 'static>(self, cx: &mut ViewContext<V>) -> Self {
elevated(self, cx, ElevationIndex::Surface)
}
@ -91,10 +73,7 @@ pub trait StyledExt: Styled {
/// Sets `bg()`, `rounded_lg()`, `border()`, `border_color()`, `shadow()`
///
/// Examples: Notifications, Palettes, Detached/Floating Windows, Detached/Floating Panels
fn elevation_2<V: 'static>(self, cx: &mut ViewContext<V>) -> Self
where
Self: Styled + Sized,
{
fn elevation_2<V: 'static>(self, cx: &mut ViewContext<V>) -> Self {
elevated(self, cx, ElevationIndex::ElevatedSurface)
}
@ -109,19 +88,9 @@ pub trait StyledExt: Styled {
/// Sets `bg()`, `rounded_lg()`, `border()`, `border_color()`, `shadow()`
///
/// Examples: Settings Modal, Channel Management, Wizards/Setup UI, Dialogs
fn elevation_4<V: 'static>(self, cx: &mut ViewContext<V>) -> Self
where
Self: Styled + Sized,
{
fn elevation_4<V: 'static>(self, cx: &mut ViewContext<V>) -> Self {
elevated(self, cx, ElevationIndex::ModalSurface)
}
}
impl<V, I, F> StyledExt for Div<V, I, F>
where
I: ElementInteractivity<V>,
F: ElementFocus<V>,
{
}
impl<V> StyledExt for UniformList<V> {}
impl<E: Styled> StyledExt for E {}

View file

@ -1,6 +1,6 @@
use crate::prelude::*;
use crate::{Icon, IconButton, Label, Panel, PanelSide};
use gpui::{rems, AbsoluteLength};
use gpui::{prelude::*, rems, AbsoluteLength};
#[derive(Component)]
pub struct AssistantPanel {

View file

@ -1,9 +1,7 @@
use crate::{h_stack, prelude::*, HighlightedText};
use gpui::{prelude::*, Div};
use std::path::PathBuf;
use crate::prelude::*;
use crate::{h_stack, HighlightedText};
use gpui::Div;
#[derive(Clone)]
pub struct Symbol(pub Vec<HighlightedText>);

View file

@ -1,7 +1,7 @@
use gpui::{Div, Render, View, VisualContext};
use crate::prelude::*;
use crate::{h_stack, Icon, IconButton, IconColor, Input};
use crate::{h_stack, Icon, IconButton, Input, TextColor};
#[derive(Clone)]
pub struct BufferSearch {
@ -36,7 +36,7 @@ impl Render for BufferSearch {
.child(
h_stack().child(Input::new("Search")).child(
IconButton::<Self>::new("replace", Icon::Replace)
.when(self.is_replace_open, |this| this.color(IconColor::Accent))
.when(self.is_replace_open, |this| this.color(TextColor::Accent))
.on_click(|buffer_search, cx| {
buffer_search.toggle_replace(cx);
}),

View file

@ -1,7 +1,6 @@
use crate::{prelude::*, Icon, IconButton, Input, Label};
use chrono::NaiveDateTime;
use crate::prelude::*;
use crate::{Icon, IconButton, Input, Label, LabelColor};
use gpui::prelude::*;
#[derive(Component)]
pub struct ChatPanel {
@ -95,7 +94,7 @@ impl ChatMessage {
.child(Label::new(self.author.clone()))
.child(
Label::new(self.sent_at.format("%m/%d/%Y").to_string())
.color(LabelColor::Muted),
.color(TextColor::Muted),
),
)
.child(div().child(Label::new(self.text.clone())))

View file

@ -1,7 +1,8 @@
use crate::{prelude::*, Toggle};
use crate::{
static_collab_panel_channels, static_collab_panel_current_call, v_stack, Icon, List, ListHeader,
prelude::*, static_collab_panel_channels, static_collab_panel_current_call, v_stack, Icon,
List, ListHeader, Toggle,
};
use gpui::prelude::*;
#[derive(Component)]
pub struct CollabPanel {

View file

@ -1,4 +1,4 @@
use crate::{prelude::*, Button, Label, LabelColor, Modal};
use crate::{prelude::*, Button, Label, Modal, TextColor};
#[derive(Component)]
pub struct CopilotModal {
@ -14,7 +14,7 @@ impl CopilotModal {
div().id(self.id.clone()).child(
Modal::new("some-id")
.title("Connect Copilot to Zed")
.child(Label::new("You can update your settings or sign out from the Copilot menu in the status bar.").color(LabelColor::Muted))
.child(Label::new("You can update your settings or sign out from the Copilot menu in the status bar.").color(TextColor::Muted))
.primary_action(Button::new("Connect to Github").variant(ButtonVariant::Filled)),
)
}

View file

@ -5,7 +5,7 @@ use gpui::{Div, Render, View, VisualContext};
use crate::prelude::*;
use crate::{
hello_world_rust_editor_with_status_example, v_stack, Breadcrumb, Buffer, BufferSearch, Icon,
IconButton, IconColor, Symbol, Tab, TabBar, Toolbar,
IconButton, Symbol, Tab, TabBar, TextColor, Toolbar,
};
#[derive(Clone)]
@ -60,12 +60,12 @@ impl Render for EditorPane {
Toolbar::new()
.left_item(Breadcrumb::new(self.path.clone(), self.symbols.clone()))
.right_items(vec![
IconButton::new("toggle_inlay_hints", Icon::InlayHint),
IconButton::<Self>::new("toggle_inlay_hints", Icon::InlayHint),
IconButton::<Self>::new("buffer_search", Icon::MagnifyingGlass)
.when(self.is_buffer_search_open, |this| {
this.color(IconColor::Accent)
this.color(TextColor::Accent)
})
.on_click(|editor, cx| {
.on_click(|editor: &mut Self, cx| {
editor.toggle_buffer_search(cx);
}),
IconButton::new("inline_assist", Icon::MagicWand),

View file

@ -1,10 +1,9 @@
use crate::utils::naive_format_distance_from_now;
use crate::{
h_stack, prelude::*, static_new_notification_items_2, v_stack, Avatar, ButtonOrIconButton,
Icon, IconElement, Label, LabelColor, LineHeightStyle, ListHeaderMeta, ListSeparator,
PublicPlayer, UnreadIndicator,
h_stack, prelude::*, static_new_notification_items_2, utils::naive_format_distance_from_now,
v_stack, Avatar, ButtonOrIconButton, ClickHandler, Icon, IconElement, Label, LineHeightStyle,
ListHeader, ListHeaderMeta, ListSeparator, PublicPlayer, TextColor, UnreadIndicator,
};
use crate::{ClickHandler, ListHeader};
use gpui::prelude::*;
#[derive(Component)]
pub struct NotificationsPanel {
@ -48,7 +47,7 @@ impl NotificationsPanel {
.border_color(cx.theme().colors().border_variant)
.child(
Label::new("Search...")
.color(LabelColor::Placeholder)
.color(TextColor::Placeholder)
.line_height_style(LineHeightStyle::UILabel),
),
)
@ -252,7 +251,7 @@ impl<V> Notification<V> {
if let Some(icon) = icon {
meta_el = meta_el.child(IconElement::new(icon.clone()));
}
meta_el.child(Label::new(text.clone()).color(LabelColor::Muted))
meta_el.child(Label::new(text.clone()).color(TextColor::Muted))
})
.collect::<Vec<_>>(),
)
@ -311,7 +310,7 @@ impl<V> Notification<V> {
true,
true,
))
.color(LabelColor::Muted),
.color(TextColor::Muted),
)
.child(self.render_meta_items(cx)),
)
@ -321,11 +320,11 @@ impl<V> Notification<V> {
// Show the taken_message
(Some(_), Some(action_taken)) => h_stack()
.children(action_taken.taken_message.0.map(|icon| {
IconElement::new(icon).color(crate::IconColor::Muted)
IconElement::new(icon).color(crate::TextColor::Muted)
}))
.child(
Label::new(action_taken.taken_message.1.clone())
.color(LabelColor::Muted),
.color(TextColor::Muted),
),
// Show the actions
(Some(actions), None) => {

View file

@ -59,7 +59,7 @@ impl<V: 'static> Pane<V> {
}
}
impl<V: 'static> ParentElement<V> for Pane<V> {
impl<V: 'static> ParentComponent<V> for Pane<V> {
fn children_mut(&mut self) -> &mut SmallVec<[AnyElement<V>; 2]> {
&mut self.children
}

View file

@ -1,7 +1,8 @@
use crate::prelude::*;
use crate::{
static_project_panel_project_items, static_project_panel_single_items, Input, List, ListHeader,
prelude::*, static_project_panel_project_items, static_project_panel_single_items, Input, List,
ListHeader,
};
use gpui::prelude::*;
#[derive(Component)]
pub struct ProjectPanel {

View file

@ -1,7 +1,7 @@
use std::sync::Arc;
use crate::prelude::*;
use crate::{Button, Icon, IconButton, IconColor, ToolDivider, Workspace};
use crate::{Button, Icon, IconButton, TextColor, ToolDivider, Workspace};
#[derive(Default, PartialEq)]
pub enum Tool {
@ -110,18 +110,18 @@ impl StatusBar {
.child(
IconButton::<Workspace>::new("project_panel", Icon::FileTree)
.when(workspace.is_project_panel_open(), |this| {
this.color(IconColor::Accent)
this.color(TextColor::Accent)
})
.on_click(|workspace, cx| {
.on_click(|workspace: &mut Workspace, cx| {
workspace.toggle_project_panel(cx);
}),
)
.child(
IconButton::<Workspace>::new("collab_panel", Icon::Hash)
.when(workspace.is_collab_panel_open(), |this| {
this.color(IconColor::Accent)
this.color(TextColor::Accent)
})
.on_click(|workspace, cx| {
.on_click(|workspace: &mut Workspace, cx| {
workspace.toggle_collab_panel();
}),
)
@ -174,27 +174,27 @@ impl StatusBar {
.child(
IconButton::<Workspace>::new("terminal", Icon::Terminal)
.when(workspace.is_terminal_open(), |this| {
this.color(IconColor::Accent)
this.color(TextColor::Accent)
})
.on_click(|workspace, cx| {
.on_click(|workspace: &mut Workspace, cx| {
workspace.toggle_terminal(cx);
}),
)
.child(
IconButton::<Workspace>::new("chat_panel", Icon::MessageBubbles)
.when(workspace.is_chat_panel_open(), |this| {
this.color(IconColor::Accent)
this.color(TextColor::Accent)
})
.on_click(|workspace, cx| {
.on_click(|workspace: &mut Workspace, cx| {
workspace.toggle_chat_panel(cx);
}),
)
.child(
IconButton::<Workspace>::new("assistant_panel", Icon::Ai)
.when(workspace.is_assistant_panel_open(), |this| {
this.color(IconColor::Accent)
this.color(TextColor::Accent)
})
.on_click(|workspace, cx| {
.on_click(|workspace: &mut Workspace, cx| {
workspace.toggle_assistant_panel(cx);
}),
),

View file

@ -1,5 +1,5 @@
use crate::prelude::*;
use crate::{Icon, IconButton, Tab};
use crate::{prelude::*, Icon, IconButton, Tab};
use gpui::prelude::*;
#[derive(Component)]
pub struct TabBar {

View file

@ -6,8 +6,8 @@ use gpui::{Div, Render, View, VisualContext};
use crate::prelude::*;
use crate::settings::user_settings;
use crate::{
Avatar, Button, Icon, IconButton, IconColor, MicStatus, PlayerStack, PlayerWithCallStatus,
ScreenShareStatus, ToolDivider, TrafficLights,
Avatar, Button, Icon, IconButton, MicStatus, PlayerStack, PlayerWithCallStatus,
ScreenShareStatus, TextColor, ToolDivider, TrafficLights,
};
#[derive(Clone)]
@ -152,21 +152,25 @@ impl Render for TitleBar {
.gap_1()
.child(
IconButton::<TitleBar>::new("toggle_mic_status", Icon::Mic)
.when(self.is_mic_muted(), |this| this.color(IconColor::Error))
.on_click(|title_bar, cx| title_bar.toggle_mic_status(cx)),
.when(self.is_mic_muted(), |this| this.color(TextColor::Error))
.on_click(|title_bar: &mut TitleBar, cx| {
title_bar.toggle_mic_status(cx)
}),
)
.child(
IconButton::<TitleBar>::new("toggle_deafened", Icon::AudioOn)
.when(self.is_deafened, |this| this.color(IconColor::Error))
.on_click(|title_bar, cx| title_bar.toggle_deafened(cx)),
.when(self.is_deafened, |this| this.color(TextColor::Error))
.on_click(|title_bar: &mut TitleBar, cx| {
title_bar.toggle_deafened(cx)
}),
)
.child(
IconButton::<TitleBar>::new("toggle_screen_share", Icon::Screen)
.when(
self.screen_share_status == ScreenShareStatus::Shared,
|this| this.color(IconColor::Accent),
|this| this.color(TextColor::Accent),
)
.on_click(|title_bar, cx| {
.on_click(|title_bar: &mut TitleBar, cx| {
title_bar.toggle_screen_share_status(cx)
}),
),

View file

@ -206,13 +206,14 @@ impl Render for Workspace {
.child(self.editor_1.clone())],
SplitDirection::Horizontal,
);
let ui_font = ThemeSettings::get_global(cx).ui_font.family.clone();
div()
.relative()
.size_full()
.flex()
.flex_col()
.font("Zed Sans")
.font(ui_font)
.gap_0()
.justify_start()
.items_start()