init tab_bar

This commit is contained in:
Nate Butler 2023-09-09 13:38:57 -04:00
parent 69f380b689
commit 9bb8eae985
7 changed files with 171 additions and 27 deletions

View file

@ -7,16 +7,16 @@ use gpui2::{Element, ParentElement, ViewContext};
#[derive(Element)]
struct IconButton {
path: &'static str,
variant: Variant,
variant: ButtonVariant,
}
#[derive(PartialEq)]
pub enum Variant {
pub enum ButtonVariant {
Ghost,
Filled,
}
pub fn icon_button<V: 'static>(path: &'static str, variant: Variant) -> impl Element<V> {
pub fn icon_button<V: 'static>(path: &'static str, variant: ButtonVariant) -> impl Element<V> {
IconButton { path, variant }
}
@ -25,8 +25,8 @@ impl IconButton {
let theme = theme(cx);
let mut div = div();
if self.variant == Variant::Filled {
div = div.fill(theme.middle.base.default.background);
if self.variant == ButtonVariant::Filled {
div = div.fill(theme.highest.base.default.background);
}
div.w_7()
@ -35,20 +35,16 @@ impl IconButton {
.items_center()
.justify_center()
.rounded_md()
.border()
.border_color(theme.middle.base.default.background)
.hover()
.fill(theme.middle.base.hovered.background)
.border_color(theme.middle.variant.hovered.border)
.fill(theme.highest.base.hovered.background)
.active()
.fill(theme.middle.base.pressed.background)
.border_color(theme.middle.variant.pressed.border)
.fill(theme.highest.base.pressed.background)
.child(
svg()
.path(self.path)
.w_4()
.h_4()
.fill(theme.middle.variant.default.foreground),
.fill(theme.highest.variant.default.foreground),
)
}
}

View file

@ -1 +1,2 @@
pub(crate) mod icon_button;
pub(crate) mod tab;

View file

@ -0,0 +1,56 @@
use crate::theme::theme;
use gpui2::elements::svg;
use gpui2::style::{StyleHelpers, Styleable};
use gpui2::{elements::div, IntoElement};
use gpui2::{Element, ParentElement, ViewContext};
#[derive(Element)]
struct Tab {
title: &'static str,
active: bool,
}
pub fn tab<V: 'static>(title: &'static str, active: bool) -> impl Element<V> {
Tab { title, active }
}
impl Tab {
fn render<V: 'static>(&mut self, _: &mut V, cx: &mut ViewContext<V>) -> impl IntoElement<V> {
let theme = theme(cx);
div()
.px_2()
.py_0p5()
.flex()
.items_center()
.justify_center()
.rounded_lg()
.fill(if self.active {
theme.highest.on.default.background
} else {
theme.highest.base.default.background
})
.hover()
.fill(if self.active {
theme.highest.on.hovered.background
} else {
theme.highest.base.hovered.background
})
.active()
.fill(if self.active {
theme.highest.on.pressed.background
} else {
theme.highest.base.pressed.background
})
.child(
div()
.text_sm()
.text_color(if self.active {
theme.highest.base.default.foreground
} else {
theme.highest.variant.default.foreground
})
.child(self.title),
)
}
}

View file

@ -0,0 +1 @@
pub(crate) mod tab_bar;

View file

@ -0,0 +1,89 @@
use std::marker::PhantomData;
use crate::component::icon_button::{icon_button, ButtonVariant};
use crate::component::tab::tab;
use crate::theme::theme;
use gpui2::elements::div::ScrollState;
use gpui2::style::StyleHelpers;
use gpui2::{elements::div, IntoElement};
use gpui2::{Element, ParentElement, ViewContext};
#[derive(Element)]
pub struct TabBar<V: 'static> {
view_type: PhantomData<V>,
scroll_state: ScrollState,
}
pub fn tab_bar<V: 'static>(scroll_state: ScrollState) -> TabBar<V> {
TabBar {
view_type: PhantomData,
scroll_state,
}
}
impl<V: 'static> TabBar<V> {
fn render(&mut self, _: &mut V, cx: &mut ViewContext<V>) -> impl IntoElement<V> {
let theme = theme(cx);
div()
.w_full()
.flex()
.items_center()
.fill(theme.highest.base.default.background)
// Left Side
.child(
div()
.px_1()
.flex()
// Nate
// This isn't what I wanted, but I wanted to try to get at least SOME x overflow scroll working
// Ideally this should be on the "Tabs" div below
// So only the tabs scroll, and the nav buttons stay pinned left, and the other controls stay pinned right
.overflow_x_scroll(self.scroll_state.clone())
.gap_2()
// Nav Buttons
.child(
div()
.flex()
.items_center()
.gap_px()
.child(icon_button("icons/arrow_left.svg", ButtonVariant::Ghost))
.child(icon_button("icons/arrow_right.svg", ButtonVariant::Ghost)),
)
// Tabs
.child(
div()
.py_1()
.flex()
.items_center()
.gap_px()
.child(tab("Cargo.toml", false))
.child(tab("Channels Panel", true))
.child(tab("channels_panel.rs", false))
.child(tab("workspace.rs", false))
.child(tab("icon_button.rs", false))
.child(tab("storybook.rs", false))
.child(tab("theme.rs", false))
.child(tab("theme_registry.rs", false))
.child(tab("styleable_helpers.rs", false)),
),
)
// Right Side
.child(
div()
.px_1()
.flex()
.flex_initial()
.gap_2()
// Nav Buttons
.child(
div()
.flex()
.items_center()
.gap_px()
.child(icon_button("icons/plus.svg", ButtonVariant::Ghost))
.child(icon_button("icons/split.svg", ButtonVariant::Ghost)),
),
)
}
}

View file

@ -11,6 +11,7 @@ use simplelog::SimpleLogger;
mod collab_panel;
mod component;
mod module;
mod components;
mod element_ext;
mod theme;

View file

@ -1,8 +1,4 @@
use crate::{
collab_panel::collab_panel,
component::icon_button::{icon_button, Variant},
theme::theme,
};
use crate::{collab_panel::collab_panel, module::tab_bar::tab_bar, theme::theme};
use gpui2::{
elements::{div, div::ScrollState, img, svg},
style::{StyleHelpers, Styleable},
@ -13,6 +9,7 @@ use gpui2::{
struct WorkspaceElement {
left_scroll_state: ScrollState,
right_scroll_state: ScrollState,
tab_bar_scroll_state: ScrollState,
}
pub fn workspace<V: 'static>() -> impl Element<V> {
@ -41,17 +38,20 @@ impl WorkspaceElement {
.flex()
.flex_row()
.overflow_hidden()
.child(collab_panel(self.left_scroll_state.clone()))
// .child(collab_panel(self.left_scroll_state.clone()))
.child(
div().h_full().flex_1().child(
div()
.w_24()
.h_24()
.child(icon_button("icons/plus.svg", Variant::Ghost))
.child(icon_button("icons/x.svg", Variant::Filled)),
.h_full()
.flex_1()
.fill(theme.highest.base.default.background)
.child(
div()
.flex()
.flex_col()
.flex_1()
.child(tab_bar(self.tab_bar_scroll_state.clone())),
),
)
.child(collab_panel(self.right_scroll_state.clone())),
), // .child(collab_panel(self.right_scroll_state.clone())),
)
.child(statusbar())
}