Merge branch 'main' into refine-keybindings

Nate Butler created

Change summary

crates/command_palette2/src/command_palette.rs    |  23 +-
crates/file_finder2/src/file_finder.rs            |   2 
crates/storybook2/src/stories/picker.rs           |   1 
crates/ui2/src/components/context_menu.rs         |   2 
crates/ui2/src/components/divider.rs              |  13 -
crates/ui2/src/components/icon.rs                 |  13 -
crates/ui2/src/components/icon_button.rs          |   6 
crates/ui2/src/components/keybinding.rs           |   2 
crates/ui2/src/components/label.rs                |   8 -
crates/ui2/src/components/list.rs                 | 112 ++++++++--------
crates/ui2/src/components/stories/avatar.rs       |   2 
crates/ui2/src/components/stories/button.rs       |   4 
crates/ui2/src/components/stories/context_menu.rs |   6 
crates/ui2/src/components/stories/icon.rs         |   2 
crates/ui2/src/components/stories/input.rs        |   2 
crates/ui2/src/components/stories/keybinding.rs   |   2 
crates/ui2/src/components/stories/label.rs        |   2 
crates/ui2/src/components/stories/list_item.rs    |   2 
crates/ui2/src/components/tooltip.rs              |   2 
crates/ui2/src/prelude.rs                         |   6 
crates/ui2/src/ui2.rs                             |   2 
crates/ui2/src/utils/format_distance.rs           |  55 ++++----
22 files changed, 109 insertions(+), 160 deletions(-)

Detailed changes

crates/command_palette2/src/command_palette.rs 🔗

@@ -304,19 +304,16 @@ impl PickerDelegate for CommandPaletteDelegate {
         };
 
         Some(
-            ListItem::new(ix)
-                .variant(ui::ListItemVariant::Inset)
-                .selected(selected)
-                .child(
-                    h_stack()
-                        .w_full()
-                        .justify_between()
-                        .child(HighlightedLabel::new(
-                            command.name.clone(),
-                            r#match.positions.clone(),
-                        ))
-                        .children(KeyBinding::for_action(&*command.action, cx)),
-                ),
+            ListItem::new(ix).inset(true).selected(selected).child(
+                h_stack()
+                    .w_full()
+                    .justify_between()
+                    .child(HighlightedLabel::new(
+                        command.name.clone(),
+                        r#match.positions.clone(),
+                    ))
+                    .children(KeyBinding::for_action(&*command.action, cx)),
+            ),
         )
     }
 }

crates/file_finder2/src/file_finder.rs 🔗

@@ -719,7 +719,7 @@ impl PickerDelegate for FileFinderDelegate {
             self.labels_for_match(path_match, cx, ix);
 
         Some(
-            ListItem::new(ix).selected(selected).child(
+            ListItem::new(ix).inset(true).selected(selected).child(
                 v_stack()
                     .child(HighlightedLabel::new(file_name, file_name_positions))
                     .child(HighlightedLabel::new(full_path, full_path_positions)),

crates/ui2/src/components/context_menu.rs 🔗

@@ -264,7 +264,7 @@ impl<M: ManagedView> Element for MenuHandle<M> {
 
                 let new_menu = (builder)(cx);
                 let menu2 = menu.clone();
-                cx.subscribe(&new_menu, move |modal, e, cx| match e {
+                cx.subscribe(&new_menu, move |_modal, e, cx| match e {
                     &DismissEvent::Dismiss => {
                         *menu2.borrow_mut() = None;
                         cx.notify();

crates/ui2/src/components/divider.rs 🔗

@@ -49,17 +49,4 @@ impl Divider {
         self.inset = true;
         self
     }
-
-    fn render(self, cx: &mut WindowContext) -> impl Element {
-        div()
-            .map(|this| match self.direction {
-                DividerDirection::Horizontal => {
-                    this.h_px().w_full().when(self.inset, |this| this.mx_1p5())
-                }
-                DividerDirection::Vertical => {
-                    this.w_px().h_full().when(self.inset, |this| this.my_1p5())
-                }
-            })
-            .bg(cx.theme().colors().border_variant)
-    }
 }

crates/ui2/src/components/icon.rs 🔗

@@ -203,17 +203,4 @@ impl IconElement {
         self.size = size;
         self
     }
-
-    fn render(self, cx: &mut WindowContext) -> impl Element {
-        let svg_size = match self.size {
-            IconSize::Small => rems(0.75),
-            IconSize::Medium => rems(0.9375),
-        };
-
-        svg()
-            .size(svg_size)
-            .flex_none()
-            .path(self.path)
-            .text_color(self.color.color(cx))
-    }
 }

crates/ui2/src/components/icon_button.rs 🔗

@@ -23,15 +23,13 @@ impl RenderOnce for IconButton {
             _ => self.color,
         };
 
-        let (mut bg_color, bg_hover_color, bg_active_color) = match self.variant {
+        let (mut bg_color, bg_active_color) = match self.variant {
             ButtonVariant::Filled => (
                 cx.theme().colors().element_background,
-                cx.theme().colors().element_hover,
                 cx.theme().colors().element_active,
             ),
             ButtonVariant::Ghost => (
                 cx.theme().colors().ghost_element_background,
-                cx.theme().colors().ghost_element_hover,
                 cx.theme().colors().ghost_element_active,
             ),
         };
@@ -124,6 +122,6 @@ impl IconButton {
     }
 
     pub fn action(self, action: Box<dyn Action>) -> Self {
-        self.on_click(move |this, cx| cx.dispatch_action(action.boxed_clone()))
+        self.on_click(move |_event, cx| cx.dispatch_action(action.boxed_clone()))
     }
 }

crates/ui2/src/components/keybinding.rs 🔗

@@ -13,7 +13,7 @@ pub struct KeyBinding {
 impl RenderOnce for KeyBinding {
     type Rendered = Div;
 
-    fn render(self, cx: &mut WindowContext) -> Self::Rendered {
+    fn render(self, _cx: &mut WindowContext) -> Self::Rendered {
         h_stack()
             .flex_none()
             .gap_2()

crates/ui2/src/components/label.rs 🔗

@@ -1,6 +1,6 @@
 use crate::prelude::*;
 use crate::styled_ext::StyledExt;
-use gpui::{relative, Div, Hsla, IntoElement, StyledText, TextRun, WindowContext};
+use gpui::{relative, Div, IntoElement, StyledText, TextRun, WindowContext};
 
 #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Default)]
 pub enum LabelSize {
@@ -182,9 +182,3 @@ impl HighlightedLabel {
         self
     }
 }
-
-/// A run of text that receives the same style.
-struct Run {
-    pub text: String,
-    pub color: Hsla,
-}

crates/ui2/src/components/list.rs 🔗

@@ -12,14 +12,6 @@ use crate::{
 };
 use crate::{prelude::*, GraphicSlot};
 
-#[derive(Clone, Copy, Default, Debug, PartialEq)]
-pub enum ListItemVariant {
-    /// The list item extends to the far left and right of the list.
-    FullWidth,
-    #[default]
-    Inset,
-}
-
 pub enum ListHeaderMeta {
     Tools(Vec<IconButton>),
     // TODO: This should be a button
@@ -32,8 +24,39 @@ pub struct ListHeader {
     label: SharedString,
     left_icon: Option<Icon>,
     meta: Option<ListHeaderMeta>,
-    variant: ListItemVariant,
     toggle: Toggle,
+    inset: bool,
+}
+
+impl ListHeader {
+    pub fn new(label: impl Into<SharedString>) -> Self {
+        Self {
+            label: label.into(),
+            left_icon: None,
+            meta: None,
+            inset: false,
+            toggle: Toggle::NotToggleable,
+        }
+    }
+
+    pub fn toggle(mut self, toggle: Toggle) -> Self {
+        self.toggle = toggle;
+        self
+    }
+
+    pub fn left_icon(mut self, left_icon: Option<Icon>) -> Self {
+        self.left_icon = left_icon;
+        self
+    }
+
+    pub fn right_button(self, button: IconButton) -> Self {
+        self.meta(Some(ListHeaderMeta::Tools(vec![button])))
+    }
+
+    pub fn meta(mut self, meta: Option<ListHeaderMeta>) -> Self {
+        self.meta = meta;
+        self
+    }
 }
 
 impl RenderOnce for ListHeader {
@@ -61,7 +84,7 @@ impl RenderOnce for ListHeader {
             .child(
                 div()
                     .h_5()
-                    .when(self.variant == ListItemVariant::Inset, |this| this.px_2())
+                    .when(self.inset, |this| this.px_2())
                     .flex()
                     .flex_1()
                     .items_center()
@@ -90,42 +113,11 @@ impl RenderOnce for ListHeader {
     }
 }
 
-impl ListHeader {
-    pub fn new(label: impl Into<SharedString>) -> Self {
-        Self {
-            label: label.into(),
-            left_icon: None,
-            meta: None,
-            variant: ListItemVariant::default(),
-            toggle: Toggle::NotToggleable,
-        }
-    }
-
-    pub fn toggle(mut self, toggle: Toggle) -> Self {
-        self.toggle = toggle;
-        self
-    }
-
-    pub fn left_icon(mut self, left_icon: Option<Icon>) -> Self {
-        self.left_icon = left_icon;
-        self
-    }
-
-    pub fn right_button(self, button: IconButton) -> Self {
-        self.meta(Some(ListHeaderMeta::Tools(vec![button])))
-    }
-
-    pub fn meta(mut self, meta: Option<ListHeaderMeta>) -> Self {
-        self.meta = meta;
-        self
-    }
-}
-
 #[derive(IntoElement, Clone)]
 pub struct ListSubHeader {
     label: SharedString,
     left_icon: Option<Icon>,
-    variant: ListItemVariant,
+    inset: bool,
 }
 
 impl ListSubHeader {
@@ -133,7 +125,7 @@ impl ListSubHeader {
         Self {
             label: label.into(),
             left_icon: None,
-            variant: ListItemVariant::default(),
+            inset: false,
         }
     }
 
@@ -146,11 +138,11 @@ impl ListSubHeader {
 impl RenderOnce for ListSubHeader {
     type Rendered = Div;
 
-    fn render(self, cx: &mut WindowContext) -> Self::Rendered {
+    fn render(self, _cx: &mut WindowContext) -> Self::Rendered {
         h_stack().flex_1().w_full().relative().py_1().child(
             div()
                 .h_6()
-                .when(self.variant == ListItemVariant::Inset, |this| this.px_2())
+                .when(self.inset, |this| this.px_2())
                 .flex()
                 .flex_1()
                 .w_full()
@@ -176,16 +168,14 @@ impl RenderOnce for ListSubHeader {
 #[derive(IntoElement)]
 pub struct ListItem {
     id: ElementId,
-    disabled: bool,
     selected: bool,
     // TODO: Reintroduce this
     // disclosure_control_style: DisclosureControlVisibility,
     indent_level: usize,
     indent_step_size: Pixels,
     left_slot: Option<GraphicSlot>,
-    overflow: OverflowStyle,
     toggle: Toggle,
-    variant: ListItemVariant,
+    inset: bool,
     on_click: Option<Rc<dyn Fn(&ClickEvent, &mut WindowContext) + 'static>>,
     on_secondary_mouse_down: Option<Rc<dyn Fn(&MouseDownEvent, &mut WindowContext) + 'static>>,
     children: SmallVec<[AnyElement; 2]>,
@@ -195,14 +185,12 @@ impl ListItem {
     pub fn new(id: impl Into<ElementId>) -> Self {
         Self {
             id: id.into(),
-            disabled: false,
             selected: false,
             indent_level: 0,
             indent_step_size: px(12.),
             left_slot: None,
-            overflow: OverflowStyle::Hidden,
             toggle: Toggle::NotToggleable,
-            variant: ListItemVariant::default(),
+            inset: false,
             on_click: None,
             on_secondary_mouse_down: None,
             children: SmallVec::new(),
@@ -222,8 +210,8 @@ impl ListItem {
         self
     }
 
-    pub fn variant(mut self, variant: ListItemVariant) -> Self {
-        self.variant = variant;
+    pub fn inset(mut self, inset: bool) -> Self {
+        self.inset = inset;
         self
     }
 
@@ -283,20 +271,26 @@ impl RenderOnce for ListItem {
         div()
             .id(self.id)
             .relative()
-            .hover(|mut style| {
-                style.background = Some(cx.theme().colors().editor_background.into());
-                style
-            })
             // TODO: Add focus state
             // .when(self.state == InteractionState::Focused, |this| {
             //     this.border()
             //         .border_color(cx.theme().colors().border_focused)
             // })
+            .when(self.inset, |this| this.rounded_md())
             .hover(|style| style.bg(cx.theme().colors().ghost_element_hover))
             .active(|style| style.bg(cx.theme().colors().ghost_element_active))
             .when(self.selected, |this| {
                 this.bg(cx.theme().colors().ghost_element_selected)
             })
+            .when_some(self.on_click.clone(), |this, on_click| {
+                this.on_click(move |event, cx| {
+                    // HACK: GPUI currently fires `on_click` with any mouse button,
+                    // but we only care about the left button.
+                    if event.down.button == MouseButton::Left {
+                        (on_click)(event, cx)
+                    }
+                })
+            })
             .when_some(self.on_secondary_mouse_down, |this, on_mouse_down| {
                 this.on_mouse_down(MouseButton::Right, move |event, cx| {
                     (on_mouse_down)(event, cx)
@@ -304,7 +298,7 @@ impl RenderOnce for ListItem {
             })
             .child(
                 div()
-                    .when(self.variant == ListItemVariant::Inset, |this| this.px_2())
+                    .when(self.inset, |this| this.px_2())
                     .ml(self.indent_level as f32 * self.indent_step_size)
                     .flex()
                     .gap_1()
@@ -367,7 +361,7 @@ pub struct List {
 impl RenderOnce for List {
     type Rendered = Div;
 
-    fn render(self, cx: &mut WindowContext) -> Self::Rendered {
+    fn render(self, _cx: &mut WindowContext) -> Self::Rendered {
         let list_content = match (self.children.is_empty(), self.toggle) {
             (false, _) => div().children(self.children),
             (true, Toggle::Toggled(false)) => div(),

crates/ui2/src/components/stories/avatar.rs 🔗

@@ -9,7 +9,7 @@ pub struct AvatarStory;
 impl Render for AvatarStory {
     type Element = Div;
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
+    fn render(&mut self, _cx: &mut ViewContext<Self>) -> Self::Element {
         Story::container()
             .child(Story::title_for::<Avatar>())
             .child(Story::label("Default"))

crates/ui2/src/components/stories/button.rs 🔗

@@ -10,7 +10,7 @@ pub struct ButtonStory;
 impl Render for ButtonStory {
     type Element = Div;
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
+    fn render(&mut self, _cx: &mut ViewContext<Self>) -> Self::Element {
         let states = InteractionState::iter();
 
         Story::container()
@@ -139,7 +139,7 @@ impl Render for ButtonStory {
             .child(
                 Button::new("Label")
                     .variant(ButtonVariant::Ghost)
-                    .on_click(|_, cx| println!("Button clicked.")),
+                    .on_click(|_, _cx| println!("Button clicked.")),
             )
     }
 }

crates/ui2/src/components/stories/context_menu.rs 🔗

@@ -10,11 +10,11 @@ fn build_menu(cx: &mut WindowContext, header: impl Into<SharedString>) -> View<C
     ContextMenu::build(cx, |menu, _| {
         menu.header(header)
             .separator()
-            .entry("Print current time", |v, cx| {
+            .entry("Print current time", |_event, cx| {
                 println!("dispatching PrintCurrentTime action");
                 cx.dispatch_action(PrintCurrentDate.boxed_clone())
             })
-            .entry("Print best foot", |v, cx| {
+            .entry("Print best foot", |_event, cx| {
                 cx.dispatch_action(PrintBestFood.boxed_clone())
             })
     })
@@ -25,7 +25,7 @@ pub struct ContextMenuStory;
 impl Render for ContextMenuStory {
     type Element = Div;
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
+    fn render(&mut self, _cx: &mut ViewContext<Self>) -> Self::Element {
         Story::container()
             .on_action(|_: &PrintCurrentDate, _| {
                 println!("printing unix time!");

crates/ui2/src/components/stories/icon.rs 🔗

@@ -10,7 +10,7 @@ pub struct IconStory;
 impl Render for IconStory {
     type Element = Div;
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
+    fn render(&mut self, _cx: &mut ViewContext<Self>) -> Self::Element {
         let icons = Icon::iter();
 
         Story::container()

crates/ui2/src/components/stories/input.rs 🔗

@@ -9,7 +9,7 @@ pub struct InputStory;
 impl Render for InputStory {
     type Element = Div;
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
+    fn render(&mut self, _cx: &mut ViewContext<Self>) -> Self::Element {
         Story::container()
             .child(Story::title_for::<Input>())
             .child(Story::label("Default"))

crates/ui2/src/components/stories/keybinding.rs 🔗

@@ -16,7 +16,7 @@ pub fn binding(key: &str) -> gpui::KeyBinding {
 impl Render for KeybindingStory {
     type Element = Div;
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
+    fn render(&mut self, _cx: &mut ViewContext<Self>) -> Self::Element {
         let all_modifier_permutations = ["ctrl", "alt", "cmd", "shift"].into_iter().permutations(2);
 
         Story::container()

crates/ui2/src/components/stories/label.rs 🔗

@@ -9,7 +9,7 @@ pub struct LabelStory;
 impl Render for LabelStory {
     type Element = Div;
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
+    fn render(&mut self, _cx: &mut ViewContext<Self>) -> Self::Element {
         Story::container()
             .child(Story::title_for::<Label>())
             .child(Story::label("Default"))

crates/ui2/src/components/stories/list_item.rs 🔗

@@ -9,7 +9,7 @@ pub struct ListItemStory;
 impl Render for ListItemStory {
     type Element = Div;
 
-    fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
+    fn render(&mut self, _cx: &mut ViewContext<Self>) -> Self::Element {
         Story::container()
             .child(Story::title_for::<ListItem>())
             .child(Story::label("Default"))

crates/ui2/src/components/tooltip.rs 🔗

@@ -13,7 +13,7 @@ pub struct Tooltip {
 
 impl Tooltip {
     pub fn text(title: impl Into<SharedString>, cx: &mut WindowContext) -> AnyView {
-        cx.build_view(|cx| Self {
+        cx.build_view(|_cx| Self {
             title: title.into(),
             meta: None,
             key_binding: None,

crates/ui2/src/prelude.rs 🔗

@@ -16,12 +16,6 @@ pub enum IconSide {
     Right,
 }
 
-#[derive(Debug, PartialEq, Eq, Clone, Copy, EnumIter)]
-pub enum OverflowStyle {
-    Hidden,
-    Wrap,
-}
-
 #[derive(Default, PartialEq, Copy, Clone, EnumIter, strum::Display)]
 pub enum InteractionState {
     /// An element that is enabled and not hovered, active, focused, or disabled.

crates/ui2/src/ui2.rs 🔗

@@ -11,8 +11,6 @@
 #![doc = include_str!("../docs/hello-world.md")]
 #![doc = include_str!("../docs/building-ui.md")]
 #![doc = include_str!("../docs/todo.md")]
-// TODO: Fix warnings instead of supressing.
-#![allow(dead_code, unused_variables)]
 
 mod components;
 pub mod prelude;

crates/ui2/src/utils/format_distance.rs 🔗

@@ -16,55 +16,54 @@ fn distance_in_seconds(date: NaiveDateTime, base_date: NaiveDateTime) -> i64 {
 fn distance_string(distance: i64, include_seconds: bool, add_suffix: bool) -> String {
     let suffix = if distance < 0 { " from now" } else { " ago" };
 
-    let d = distance.abs();
+    let distance = distance.abs();
 
-    let minutes = d / 60;
-    let hours = d / 3600;
-    let days = d / 86400;
-    let months = d / 2592000;
-    let years = d / 31536000;
+    let minutes = distance / 60;
+    let hours = distance / 3_600;
+    let days = distance / 86_400;
+    let months = distance / 2_592_000;
 
-    let string = if d < 5 && include_seconds {
+    let string = if distance < 5 && include_seconds {
         "less than 5 seconds".to_string()
-    } else if d < 10 && include_seconds {
+    } else if distance < 10 && include_seconds {
         "less than 10 seconds".to_string()
-    } else if d < 20 && include_seconds {
+    } else if distance < 20 && include_seconds {
         "less than 20 seconds".to_string()
-    } else if d < 40 && include_seconds {
+    } else if distance < 40 && include_seconds {
         "half a minute".to_string()
-    } else if d < 60 && include_seconds {
+    } else if distance < 60 && include_seconds {
         "less than a minute".to_string()
-    } else if d < 90 && include_seconds {
+    } else if distance < 90 && include_seconds {
         "1 minute".to_string()
-    } else if d < 30 {
+    } else if distance < 30 {
         "less than a minute".to_string()
-    } else if d < 90 {
+    } else if distance < 90 {
         "1 minute".to_string()
-    } else if d < 2700 {
+    } else if distance < 2_700 {
         format!("{} minutes", minutes)
-    } else if d < 5400 {
+    } else if distance < 5_400 {
         "about 1 hour".to_string()
-    } else if d < 86400 {
+    } else if distance < 86_400 {
         format!("about {} hours", hours)
-    } else if d < 172800 {
+    } else if distance < 172_800 {
         "1 day".to_string()
-    } else if d < 2592000 {
+    } else if distance < 2_592_000 {
         format!("{} days", days)
-    } else if d < 5184000 {
+    } else if distance < 5_184_000 {
         "about 1 month".to_string()
-    } else if d < 7776000 {
+    } else if distance < 7_776_000 {
         "about 2 months".to_string()
-    } else if d < 31540000 {
+    } else if distance < 31_540_000 {
         format!("{} months", months)
-    } else if d < 39425000 {
+    } else if distance < 39_425_000 {
         "about 1 year".to_string()
-    } else if d < 55195000 {
+    } else if distance < 55_195_000 {
         "over 1 year".to_string()
-    } else if d < 63080000 {
+    } else if distance < 63_080_000 {
         "almost 2 years".to_string()
     } else {
-        let years = d / 31536000;
-        let remaining_months = (d % 31536000) / 2592000;
+        let years = distance / 31_536_000;
+        let remaining_months = (distance % 31_536_000) / 2_592_000;
 
         if remaining_months < 3 {
             format!("about {} years", years)
@@ -76,7 +75,7 @@ fn distance_string(distance: i64, include_seconds: bool, add_suffix: bool) -> St
     };
 
     if add_suffix {
-        return format!("{}{}", string, suffix);
+        format!("{}{}", string, suffix)
     } else {
         string
     }