init tab_bar
This commit is contained in:
parent
69f380b689
commit
9bb8eae985
7 changed files with 171 additions and 27 deletions
|
@ -7,16 +7,16 @@ use gpui2::{Element, ParentElement, ViewContext};
|
||||||
#[derive(Element)]
|
#[derive(Element)]
|
||||||
struct IconButton {
|
struct IconButton {
|
||||||
path: &'static str,
|
path: &'static str,
|
||||||
variant: Variant,
|
variant: ButtonVariant,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq)]
|
#[derive(PartialEq)]
|
||||||
pub enum Variant {
|
pub enum ButtonVariant {
|
||||||
Ghost,
|
Ghost,
|
||||||
Filled,
|
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 }
|
IconButton { path, variant }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,8 +25,8 @@ impl IconButton {
|
||||||
let theme = theme(cx);
|
let theme = theme(cx);
|
||||||
let mut div = div();
|
let mut div = div();
|
||||||
|
|
||||||
if self.variant == Variant::Filled {
|
if self.variant == ButtonVariant::Filled {
|
||||||
div = div.fill(theme.middle.base.default.background);
|
div = div.fill(theme.highest.base.default.background);
|
||||||
}
|
}
|
||||||
|
|
||||||
div.w_7()
|
div.w_7()
|
||||||
|
@ -35,20 +35,16 @@ impl IconButton {
|
||||||
.items_center()
|
.items_center()
|
||||||
.justify_center()
|
.justify_center()
|
||||||
.rounded_md()
|
.rounded_md()
|
||||||
.border()
|
|
||||||
.border_color(theme.middle.base.default.background)
|
|
||||||
.hover()
|
.hover()
|
||||||
.fill(theme.middle.base.hovered.background)
|
.fill(theme.highest.base.hovered.background)
|
||||||
.border_color(theme.middle.variant.hovered.border)
|
|
||||||
.active()
|
.active()
|
||||||
.fill(theme.middle.base.pressed.background)
|
.fill(theme.highest.base.pressed.background)
|
||||||
.border_color(theme.middle.variant.pressed.border)
|
|
||||||
.child(
|
.child(
|
||||||
svg()
|
svg()
|
||||||
.path(self.path)
|
.path(self.path)
|
||||||
.w_4()
|
.w_4()
|
||||||
.h_4()
|
.h_4()
|
||||||
.fill(theme.middle.variant.default.foreground),
|
.fill(theme.highest.variant.default.foreground),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1,2 @@
|
||||||
pub(crate) mod icon_button;
|
pub(crate) mod icon_button;
|
||||||
|
pub(crate) mod tab;
|
||||||
|
|
56
crates/storybook/src/component/tab.rs
Normal file
56
crates/storybook/src/component/tab.rs
Normal 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),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
1
crates/storybook/src/module/mod.rs
Normal file
1
crates/storybook/src/module/mod.rs
Normal file
|
@ -0,0 +1 @@
|
||||||
|
pub(crate) mod tab_bar;
|
89
crates/storybook/src/module/tab_bar.rs
Normal file
89
crates/storybook/src/module/tab_bar.rs
Normal 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)),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,6 +11,7 @@ use simplelog::SimpleLogger;
|
||||||
|
|
||||||
mod collab_panel;
|
mod collab_panel;
|
||||||
mod component;
|
mod component;
|
||||||
|
mod module;
|
||||||
mod components;
|
mod components;
|
||||||
mod element_ext;
|
mod element_ext;
|
||||||
mod theme;
|
mod theme;
|
||||||
|
|
|
@ -1,8 +1,4 @@
|
||||||
use crate::{
|
use crate::{collab_panel::collab_panel, module::tab_bar::tab_bar, theme::theme};
|
||||||
collab_panel::collab_panel,
|
|
||||||
component::icon_button::{icon_button, Variant},
|
|
||||||
theme::theme,
|
|
||||||
};
|
|
||||||
use gpui2::{
|
use gpui2::{
|
||||||
elements::{div, div::ScrollState, img, svg},
|
elements::{div, div::ScrollState, img, svg},
|
||||||
style::{StyleHelpers, Styleable},
|
style::{StyleHelpers, Styleable},
|
||||||
|
@ -13,6 +9,7 @@ use gpui2::{
|
||||||
struct WorkspaceElement {
|
struct WorkspaceElement {
|
||||||
left_scroll_state: ScrollState,
|
left_scroll_state: ScrollState,
|
||||||
right_scroll_state: ScrollState,
|
right_scroll_state: ScrollState,
|
||||||
|
tab_bar_scroll_state: ScrollState,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn workspace<V: 'static>() -> impl Element<V> {
|
pub fn workspace<V: 'static>() -> impl Element<V> {
|
||||||
|
@ -41,17 +38,20 @@ impl WorkspaceElement {
|
||||||
.flex()
|
.flex()
|
||||||
.flex_row()
|
.flex_row()
|
||||||
.overflow_hidden()
|
.overflow_hidden()
|
||||||
.child(collab_panel(self.left_scroll_state.clone()))
|
// .child(collab_panel(self.left_scroll_state.clone()))
|
||||||
.child(
|
.child(
|
||||||
div().h_full().flex_1().child(
|
div()
|
||||||
div()
|
.h_full()
|
||||||
.w_24()
|
.flex_1()
|
||||||
.h_24()
|
.fill(theme.highest.base.default.background)
|
||||||
.child(icon_button("icons/plus.svg", Variant::Ghost))
|
.child(
|
||||||
.child(icon_button("icons/x.svg", Variant::Filled)),
|
div()
|
||||||
),
|
.flex()
|
||||||
)
|
.flex_col()
|
||||||
.child(collab_panel(self.right_scroll_state.clone())),
|
.flex_1()
|
||||||
|
.child(tab_bar(self.tab_bar_scroll_state.clone())),
|
||||||
|
),
|
||||||
|
), // .child(collab_panel(self.right_scroll_state.clone())),
|
||||||
)
|
)
|
||||||
.child(statusbar())
|
.child(statusbar())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue