UI progress (#3405)

Nate Butler created

[[PR Description]]

- Start outlining unfinished elements in `gpui::red()`
- Update tabs so they don't jump when activated
- Mock out a number of ui elements we haven't started yet.

Release Notes:

- N/A

Change summary

crates/collab_ui2/src/collab_titlebar_item.rs |  6 +
crates/theme2/src/one_themes.rs               |  4 
crates/theme2/src/theme2.rs                   |  6 +
crates/ui2/src/components/icon.rs             |  6 +
crates/ui2/src/components/icon_button.rs      |  2 
crates/workspace2/src/pane.rs                 | 75 +++++++++++++----
crates/workspace2/src/status_bar.rs           | 87 ++++++++++++++++++++
crates/workspace2/src/toolbar.rs              | 18 +++
8 files changed, 177 insertions(+), 27 deletions(-)

Detailed changes

crates/collab_ui2/src/collab_titlebar_item.rs 🔗

@@ -111,6 +111,8 @@ impl Render for CollabTitlebarItem {
                     // TODO - Add player menu
                     .child(
                         div()
+                            .border()
+                            .border_color(gpui::red())
                             .id("project_owner_indicator")
                             .child(
                                 Button::new("player")
@@ -122,6 +124,8 @@ impl Render for CollabTitlebarItem {
                     // TODO - Add project menu
                     .child(
                         div()
+                            .border()
+                            .border_color(gpui::red())
                             .id("titlebar_project_menu_button")
                             .child(Button::new("project_name").variant(ButtonVariant::Ghost))
                             .tooltip(move |cx| Tooltip::text("Recent Projects", cx)),
@@ -129,6 +133,8 @@ impl Render for CollabTitlebarItem {
                     // TODO - Add git menu
                     .child(
                         div()
+                            .border()
+                            .border_color(gpui::red())
                             .id("titlebar_git_menu_button")
                             .child(
                                 Button::new("branch_name")

crates/theme2/src/one_themes.rs 🔗

@@ -59,8 +59,8 @@ pub(crate) fn one_dark() -> Theme {
                 ghost_element_active: hsla(220.0 / 360., 11.8 / 100., 20.0 / 100., 1.0),
                 ghost_element_selected: hsla(224.0 / 360., 11.3 / 100., 26.1 / 100., 1.0),
                 ghost_element_disabled: hsla(224.0 / 360., 11.3 / 100., 26.1 / 100., 1.0),
-                text: hsla(222.9 / 360., 9.1 / 100., 84.9 / 100., 1.0),
-                text_muted: hsla(220.0 / 360., 6.4 / 100., 45.7 / 100., 1.0),
+                text: hsla(221. / 360., 11. / 100., 86. / 100., 1.0),
+                text_muted: hsla(218.0 / 360., 7. / 100., 46. / 100., 1.0),
                 text_placeholder: hsla(220.0 / 360., 6.6 / 100., 44.5 / 100., 1.0),
                 text_disabled: hsla(220.0 / 360., 6.6 / 100., 44.5 / 100., 1.0),
                 text_accent: hsla(222.6 / 360., 77.5 / 100., 65.1 / 100., 1.0),

crates/theme2/src/theme2.rs 🔗

@@ -134,6 +134,12 @@ impl Theme {
             ignored: self.status().ignored,
         }
     }
+
+    /// Returns the [`Appearance`] for the theme.
+    #[inline(always)]
+    pub fn appearance(&self) -> Appearance {
+        self.appearance
+    }
 }
 
 #[derive(Clone, Debug, Default)]

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

@@ -32,6 +32,9 @@ pub enum Icon {
     Close,
     Collab,
     Copilot,
+    CopilotInit,
+    CopilotError,
+    CopilotDisabled,
     Dash,
     Envelope,
     ExclamationTriangle,
@@ -93,6 +96,9 @@ impl Icon {
             Icon::Close => "icons/x.svg",
             Icon::Collab => "icons/user_group_16.svg",
             Icon::Copilot => "icons/copilot.svg",
+            Icon::CopilotInit => "icons/copilot_init.svg",
+            Icon::CopilotError => "icons/copilot_error.svg",
+            Icon::CopilotDisabled => "icons/copilot_disabled.svg",
             Icon::Dash => "icons/dash.svg",
             Icon::Envelope => "icons/feedback.svg",
             Icon::ExclamationTriangle => "icons/warning.svg",

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

@@ -37,7 +37,7 @@ impl RenderOnce for IconButton {
         };
 
         if self.selected {
-            bg_color = bg_hover_color;
+            bg_color = cx.theme().colors().element_selected;
         }
 
         let mut button = h_stack()

crates/workspace2/src/pane.rs 🔗

@@ -1379,6 +1379,7 @@ impl Pane {
         };
 
         let close_right = ItemSettings::get_global(cx).close_position.right();
+        let is_active = ix == self.active_item_index;
 
         div()
             .group("")
@@ -1407,10 +1408,24 @@ impl Pane {
             .py_1()
             .bg(tab_bg)
             .border_color(cx.theme().colors().border)
-            .map(|this| match ix.cmp(&self.active_item_index) {
-                cmp::Ordering::Less => this.border_l(),
-                cmp::Ordering::Equal => this.border_r(),
-                cmp::Ordering::Greater => this.border_l().border_r(),
+            .text_color(if is_active {
+                cx.theme().colors().text
+            } else {
+                cx.theme().colors().text_muted
+            })
+            .map(|this| {
+                let is_last_item = ix == self.items.len() - 1;
+                match ix.cmp(&self.active_item_index) {
+                    cmp::Ordering::Less => this.border_l().mr_px(),
+                    cmp::Ordering::Greater => {
+                        if is_last_item {
+                            this.mr_px().ml_px()
+                        } else {
+                            this.border_r().ml_px()
+                        }
+                    }
+                    cmp::Ordering::Equal => this.border_l().border_r(),
+                }
             })
             // .hover(|h| h.bg(tab_hover_bg))
             // .active(|a| a.bg(tab_active_bg))
@@ -1423,14 +1438,18 @@ impl Pane {
                     .children(
                         item.has_conflict(cx)
                             .then(|| {
-                                IconElement::new(Icon::ExclamationTriangle)
-                                    .size(ui::IconSize::Small)
-                                    .color(Color::Warning)
+                                div().border().border_color(gpui::red()).child(
+                                    IconElement::new(Icon::ExclamationTriangle)
+                                        .size(ui::IconSize::Small)
+                                        .color(Color::Warning),
+                                )
                             })
                             .or(item.is_dirty(cx).then(|| {
-                                IconElement::new(Icon::ExclamationTriangle)
-                                    .size(ui::IconSize::Small)
-                                    .color(Color::Info)
+                                div().border().border_color(gpui::red()).child(
+                                    IconElement::new(Icon::ExclamationTriangle)
+                                        .size(ui::IconSize::Small)
+                                        .color(Color::Info),
+                                )
                             })),
                     )
                     .children((!close_right).then(|| close_icon()))
@@ -1461,12 +1480,22 @@ impl Pane {
                             .flex()
                             .items_center()
                             .gap_px()
-                            .child(IconButton::new("navigate_backward", Icon::ArrowLeft).state(
-                                InteractionState::Enabled.if_enabled(self.can_navigate_backward()),
-                            ))
-                            .child(IconButton::new("navigate_forward", Icon::ArrowRight).state(
-                                InteractionState::Enabled.if_enabled(self.can_navigate_forward()),
-                            )),
+                            .child(
+                                div().border().border_color(gpui::red()).child(
+                                    IconButton::new("navigate_backward", Icon::ArrowLeft).state(
+                                        InteractionState::Enabled
+                                            .if_enabled(self.can_navigate_backward()),
+                                    ),
+                                ),
+                            )
+                            .child(
+                                div().border().border_color(gpui::red()).child(
+                                    IconButton::new("navigate_forward", Icon::ArrowRight).state(
+                                        InteractionState::Enabled
+                                            .if_enabled(self.can_navigate_forward()),
+                                    ),
+                                ),
+                            ),
                     ),
             )
             .child(
@@ -1493,8 +1522,18 @@ impl Pane {
                             .flex()
                             .items_center()
                             .gap_px()
-                            .child(IconButton::new("plus", Icon::Plus))
-                            .child(IconButton::new("split", Icon::Split)),
+                            .child(
+                                div()
+                                    .border()
+                                    .border_color(gpui::red())
+                                    .child(IconButton::new("plus", Icon::Plus)),
+                            )
+                            .child(
+                                div()
+                                    .border()
+                                    .border_color(gpui::red())
+                                    .child(IconButton::new("split", Icon::Split)),
+                            ),
                     ),
             )
     }

crates/workspace2/src/status_bar.rs 🔗

@@ -6,7 +6,7 @@ use gpui::{
     WindowContext,
 };
 use theme2::ActiveTheme;
-use ui::h_stack;
+use ui::{h_stack, Button, Icon, IconButton};
 use util::ResultExt;
 
 pub trait StatusItemView: Render {
@@ -47,8 +47,89 @@ impl Render for StatusBar {
             .w_full()
             .h_8()
             .bg(cx.theme().colors().status_bar_background)
-            .child(self.render_left_tools(cx))
-            .child(self.render_right_tools(cx))
+            // Nate: I know this isn't how we render status bar tools
+            // We can move these to the correct place once we port their tools
+            .child(
+                h_stack().gap_1().child(self.render_left_tools(cx)).child(
+                    h_stack().gap_4().child(
+                        // TODO: Language Server status
+                        div()
+                            .border()
+                            .border_color(gpui::red())
+                            .child("Checking..."),
+                    ),
+                ),
+            )
+            .child(
+                h_stack()
+                    .gap_4()
+                    .child(
+                        h_stack()
+                            .gap_1()
+                            .child(
+                                // TODO: Line / column numbers
+                                div()
+                                    .border()
+                                    .border_color(gpui::red())
+                                    .child(Button::new("15:22")),
+                            )
+                            .child(
+                                // TODO: Language picker
+                                div()
+                                    .border()
+                                    .border_color(gpui::red())
+                                    .child(Button::new("Rust")),
+                            ),
+                    )
+                    .child(
+                        h_stack()
+                            .gap_1()
+                            .child(
+                                // Github tool
+                                div()
+                                    .border()
+                                    .border_color(gpui::red())
+                                    .child(IconButton::new("status-copilot", Icon::Copilot)),
+                            )
+                            .child(
+                                // Feedback Tool
+                                div()
+                                    .border()
+                                    .border_color(gpui::red())
+                                    .child(IconButton::new("status-feedback", Icon::Envelope)),
+                            ),
+                    )
+                    .child(
+                        // Bottom Dock
+                        h_stack().gap_1().child(
+                            // Terminal
+                            div()
+                                .border()
+                                .border_color(gpui::red())
+                                .child(IconButton::new("status-terminal", Icon::Terminal)),
+                        ),
+                    )
+                    .child(
+                        // Right Dock
+                        h_stack()
+                            .gap_1()
+                            .child(
+                                // Terminal
+                                div()
+                                    .border()
+                                    .border_color(gpui::red())
+                                    .child(IconButton::new("status-assistant", Icon::Ai)),
+                            )
+                            .child(
+                                // Terminal
+                                div()
+                                    .border()
+                                    .border_color(gpui::red())
+                                    .child(IconButton::new("status-chat", Icon::MessageBubbles)),
+                            ),
+                    )
+                    .child(self.render_right_tools(cx)),
+            )
     }
 }
 

crates/workspace2/src/toolbar.rs 🔗

@@ -1,6 +1,6 @@
 use crate::ItemHandle;
 use gpui::{
-    AnyView, Div, Entity, EntityId, EventEmitter, ParentElement as _, Render, Styled, View,
+    div, AnyView, Div, Entity, EntityId, EventEmitter, ParentElement as _, Render, Styled, View,
     ViewContext, WindowContext,
 };
 use theme2::ActiveTheme;
@@ -91,6 +91,8 @@ impl Render for Toolbar {
                     .child(
                         // Toolbar left side
                         h_stack()
+                            .border()
+                            .border_color(gpui::red())
                             .p_1()
                             .child(Button::new("crates"))
                             .child(Label::new("/").color(Color::Muted))
@@ -100,8 +102,18 @@ impl Render for Toolbar {
                     .child(
                         h_stack()
                             .p_1()
-                            .child(IconButton::new("buffer-search", Icon::MagnifyingGlass))
-                            .child(IconButton::new("inline-assist", Icon::MagicWand)),
+                            .child(
+                                div()
+                                    .border()
+                                    .border_color(gpui::red())
+                                    .child(IconButton::new("buffer-search", Icon::MagnifyingGlass)),
+                            )
+                            .child(
+                                div()
+                                    .border()
+                                    .border_color(gpui::red())
+                                    .child(IconButton::new("inline-assist", Icon::MagicWand)),
+                            ),
                     ),
             )
             .children(self.items.iter().map(|(child, _)| child.to_any()))