232 lines
8.2 KiB
Rust
232 lines
8.2 KiB
Rust
use ely_gpui_component::{
|
|
buttons::{Button, IconButton},
|
|
primitives::IconName,
|
|
shell::{
|
|
ActivityBar, ActivityItem, StatusBar, StatusBarItem, TabBar, Toolbar, ToolbarGroup,
|
|
ToolbarSeparator, WindowTab,
|
|
},
|
|
theme::{ActiveTheme, ControlSize, TextSize},
|
|
typography::Caption,
|
|
};
|
|
use gpui::{App, IntoElement, ParentElement, SharedString, Styled, Window, div, px};
|
|
|
|
use super::chrome::window_frame;
|
|
use crate::{probe::probe, ui::section};
|
|
|
|
fn tool(id: &'static str, icon: IconName) -> IconButton {
|
|
IconButton::new(id, icon).size(ControlSize::Sm)
|
|
}
|
|
|
|
pub fn toolbar(cx: &App) -> impl IntoElement + use<> {
|
|
section(
|
|
"Toolbar / ToolbarGroup / ToolbarSeparator",
|
|
"Tools in groups, hairlines between, one action apart.",
|
|
cx,
|
|
)
|
|
.child(
|
|
window_frame(560.0, 44.0, cx)
|
|
.justify_center()
|
|
.bg(cx.theme().colors.bg)
|
|
.child(
|
|
Toolbar::new()
|
|
.w_full()
|
|
.child(
|
|
ToolbarGroup::new()
|
|
.child(tool("tb-undo", IconName::Undo2))
|
|
.child(tool("tb-redo", IconName::Redo2)),
|
|
)
|
|
.child(ToolbarSeparator)
|
|
.child(
|
|
ToolbarGroup::new()
|
|
.child(tool("tb-bold", IconName::Bold))
|
|
.child(tool("tb-italic", IconName::Italic))
|
|
.child(tool("tb-underline", IconName::Underline)),
|
|
)
|
|
.child(ToolbarSeparator)
|
|
.child(
|
|
ToolbarGroup::new()
|
|
.child(tool("tb-left", IconName::AlignLeft))
|
|
.child(tool("tb-center", IconName::AlignCenter))
|
|
.child(tool("tb-right", IconName::AlignRight)),
|
|
)
|
|
.child(div().flex_1())
|
|
.child(
|
|
Button::new("tb-share", "Share")
|
|
.size(ControlSize::Sm)
|
|
.icon(IconName::Share2),
|
|
),
|
|
),
|
|
)
|
|
}
|
|
|
|
pub fn status_bar(cx: &App) -> impl IntoElement + use<> {
|
|
section(
|
|
"StatusBar / StatusBarItem",
|
|
"Small type at the foot. Items that act show it on hover.",
|
|
cx,
|
|
)
|
|
.child(
|
|
window_frame(560.0, 96.0, cx).justify_end().child(
|
|
StatusBar::new()
|
|
.left(
|
|
StatusBarItem::new("sb-branch")
|
|
.icon(IconName::GitBranch)
|
|
.label("main")
|
|
.tooltip("Switch branch")
|
|
.on_click(|_, _, _| log::info!("gallery: branch")),
|
|
)
|
|
.left(
|
|
StatusBarItem::new("sb-sync")
|
|
.icon(IconName::RefreshCw)
|
|
.label("Synced"),
|
|
)
|
|
.right(StatusBarItem::new("sb-cursor").label("Ln 12, Col 4"))
|
|
.right(StatusBarItem::new("sb-encoding").label("UTF-8"))
|
|
.right(
|
|
StatusBarItem::new("sb-bell")
|
|
.icon(IconName::Bell)
|
|
.tooltip("No notifications")
|
|
.on_click(|_, _, _| log::info!("gallery: notifications")),
|
|
),
|
|
),
|
|
)
|
|
}
|
|
|
|
pub fn activity_bar(window: &mut Window, cx: &mut App) -> impl IntoElement + use<> {
|
|
let selected =
|
|
window.use_keyed_state("activity-selected", cx, |_, _| SharedString::from("files"));
|
|
let current = selected.read(cx).clone();
|
|
let theme = cx.theme();
|
|
section(
|
|
"ActivityBar / NavigationRail",
|
|
"An icon rail. The mark grows in beside the chosen view.",
|
|
cx,
|
|
)
|
|
.child(
|
|
window_frame(560.0, 400.0, cx)
|
|
.flex_row()
|
|
.child(probe(
|
|
"activity",
|
|
ActivityBar::new("activity-bar")
|
|
.item(ActivityItem::new("files", IconName::Folder, "Explorer"))
|
|
.item(ActivityItem::new("search", IconName::Search, "Search"))
|
|
.item(ActivityItem::new("git", IconName::GitBranch, "Source Control").badge(3))
|
|
.item(ActivityItem::new("debug", IconName::Bug, "Run and Debug"))
|
|
.item(ActivityItem::new(
|
|
"extensions",
|
|
IconName::Puzzle,
|
|
"Extensions",
|
|
))
|
|
.footer(ActivityItem::new("account", IconName::User, "Account"))
|
|
.footer(ActivityItem::new(
|
|
"settings",
|
|
IconName::Settings,
|
|
"Settings",
|
|
))
|
|
.selected(current.clone())
|
|
.on_select(move |id, _, cx| {
|
|
let id = id.clone();
|
|
selected.update(cx, |selected, cx| {
|
|
*selected = id;
|
|
cx.notify();
|
|
})
|
|
}),
|
|
))
|
|
.child(
|
|
div()
|
|
.flex_1()
|
|
.p_5()
|
|
.bg(theme.colors.bg)
|
|
.text_size(theme.text_size(TextSize::Sm))
|
|
.text_color(theme.colors.fg_muted)
|
|
.child(SharedString::from(format!("View: {current}"))),
|
|
),
|
|
)
|
|
.child(Caption::new("NavigationRail is the same rail."))
|
|
}
|
|
|
|
#[derive(Clone)]
|
|
struct Tabs {
|
|
open: Vec<(SharedString, SharedString, IconName)>,
|
|
selected: SharedString,
|
|
next: u32,
|
|
}
|
|
|
|
pub fn tab_bar(window: &mut Window, cx: &mut App) -> impl IntoElement + use<> {
|
|
let state = window.use_keyed_state("window-tabs", cx, |_, _| Tabs {
|
|
open: vec![
|
|
("inbox".into(), "Inbox".into(), IconName::Inbox),
|
|
("roadmap".into(), "Roadmap".into(), IconName::Map),
|
|
(
|
|
"notes".into(),
|
|
"Meeting notes".into(),
|
|
IconName::NotebookPen,
|
|
),
|
|
],
|
|
selected: "roadmap".into(),
|
|
next: 1,
|
|
});
|
|
let tabs = state.read(cx).clone();
|
|
let (select, close, add, reorder) = (state.clone(), state.clone(), state.clone(), state);
|
|
let mut bar = TabBar::new("window-tab-bar")
|
|
.selected(tabs.selected.clone())
|
|
.on_select(move |id, _, cx| {
|
|
let id = id.clone();
|
|
select.update(cx, |tabs, cx| {
|
|
tabs.selected = id;
|
|
cx.notify();
|
|
})
|
|
})
|
|
.on_close(move |id, _, cx| {
|
|
let id = id.clone();
|
|
close.update(cx, |tabs, cx| {
|
|
tabs.open.retain(|(tab, _, _)| *tab != id);
|
|
if tabs.selected == id {
|
|
tabs.selected = tabs
|
|
.open
|
|
.first()
|
|
.map(|(tab, _, _)| tab.clone())
|
|
.unwrap_or_default();
|
|
}
|
|
cx.notify();
|
|
})
|
|
})
|
|
.on_add(move |_, cx| {
|
|
add.update(cx, |tabs, cx| {
|
|
let id = SharedString::from(format!("draft-{}", tabs.next));
|
|
tabs.open.push((
|
|
id.clone(),
|
|
format!("Draft {}", tabs.next).into(),
|
|
IconName::FileText,
|
|
));
|
|
tabs.next += 1;
|
|
tabs.selected = id;
|
|
cx.notify();
|
|
})
|
|
})
|
|
.on_reorder(move |from, to, _, cx| {
|
|
reorder.update(cx, |tabs, cx| {
|
|
let moved = tabs.open.remove(from);
|
|
tabs.open.insert(to, moved);
|
|
cx.notify();
|
|
})
|
|
});
|
|
for (id, title, icon) in tabs.open {
|
|
bar = bar.tab(WindowTab::new(id, title).icon(icon));
|
|
}
|
|
section(
|
|
"TabBar",
|
|
"Window tabs. New ones rise in; drag one onto another to reorder.",
|
|
cx,
|
|
)
|
|
.child(
|
|
window_frame(560.0, 120.0, cx)
|
|
.child(
|
|
div()
|
|
.p_1p5()
|
|
.child(probe("tab-bar", div().w(px(548.0)).child(bar))),
|
|
)
|
|
.child(div().flex_1().bg(cx.theme().colors.bg)),
|
|
)
|
|
}
|