panel.rs

 1//! # panel
 2use gpui::actions;
 3use ui::{Tab, prelude::*};
 4
 5actions!(
 6    panel,
 7    [
 8        /// Navigates to the next tab in the panel.
 9        NextPanelTab,
10        /// Navigates to the previous tab in the panel.
11        PreviousPanelTab
12    ]
13);
14
15pub trait PanelHeader: workspace::Panel {
16    fn header_height(&self, cx: &mut App) -> Pixels {
17        Tab::container_height(cx)
18    }
19
20    fn panel_header_container(&self, _window: &mut Window, cx: &mut App) -> Div {
21        h_flex()
22            .h(self.header_height(cx))
23            .w_full()
24            .px_1()
25            .flex_none()
26    }
27}
28
29/// Implement this trait to enable a panel to have tabs.
30pub trait PanelTabs: PanelHeader {
31    /// Returns the index of the currently selected tab.
32    fn selected_tab(&self, cx: &mut App) -> usize;
33    /// Selects the tab at the given index.
34    fn select_tab(&self, cx: &mut App, index: usize);
35    /// Moves to the next tab.
36    fn next_tab(&self, _: NextPanelTab, cx: &mut App) -> Self;
37    /// Moves to the previous tab.
38    fn previous_tab(&self, _: PreviousPanelTab, cx: &mut App) -> Self;
39}
40
41#[derive(IntoElement)]
42pub struct PanelTab {}
43
44impl RenderOnce for PanelTab {
45    fn render(self, _window: &mut Window, _cx: &mut App) -> impl IntoElement {
46        div()
47    }
48}
49
50pub fn panel_button(label: impl Into<SharedString>) -> ui::Button {
51    let label = label.into();
52    let id = ElementId::Name(label.to_lowercase().replace(' ', "_").into());
53    ui::Button::new(id, label)
54        .label_size(ui::LabelSize::Small)
55        .icon_size(ui::IconSize::Small)
56        // TODO: Change this once we use on_surface_bg in button_like
57        .layer(ui::ElevationIndex::ModalSurface)
58        .size(ui::ButtonSize::Compact)
59}
60
61pub fn panel_filled_button(label: impl Into<SharedString>) -> ui::Button {
62    panel_button(label).style(ui::ButtonStyle::Filled)
63}
64
65pub fn panel_icon_button(id: impl Into<SharedString>, icon: IconName) -> ui::IconButton {
66    let id = ElementId::Name(id.into());
67
68    IconButton::new(id, icon)
69        // TODO: Change this once we use on_surface_bg in button_like
70        .layer(ui::ElevationIndex::ModalSurface)
71}
72
73pub fn panel_filled_icon_button(id: impl Into<SharedString>, icon: IconName) -> ui::IconButton {
74    panel_icon_button(id, icon).style(ui::ButtonStyle::Filled)
75}