Files

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)),
)
}