use gpui::{SharedString, div, prelude::*, px};
use icons::Icon;
use theme::{TextStyle, Theme, Typeset};
use crate::{icons, widgets};
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Slot {
Page(usize),
Gap,
}
pub fn window(current: usize, total: usize, around: usize) -> Vec<Slot> {
if total == 0 {
return Vec::new();
}
let current = current.clamp(1, total);
let width = (2 * around + 1).min(total);
let last_start = total - width + 1;
let start = current.saturating_sub(around).clamp(1, last_start);
let end = start + width - 1;
let mut slots = Vec::with_capacity(width + 4);
if start > 1 {
slots.push(Slot::Page(1));
match start - 1 {
1 => {}
2 => slots.push(Slot::Page(2)),
_ => slots.push(Slot::Gap),
}
}
slots.extend((start..=end).map(Slot::Page));
if end < total {
match total - end {
1 => {}
2 => slots.push(Slot::Page(total - 1)),
_ => slots.push(Slot::Gap),
}
slots.push(Slot::Page(total));
}
slots
}
const BUTTON: f32 = 28.0;
pub fn pagination() -> gpui::Div {
div()
.self_start()
.flex()
.flex_row()
.items_center()
.gap(px(4.0))
}
pub fn page_button(theme: &Theme, page: usize, current: bool) -> gpui::Div {
let button = div()
.min_w(px(BUTTON))
.h(px(BUTTON))
.px(px(6.0))
.rounded(px(7.0))
.flex()
.items_center()
.justify_center()
.text_style(TextStyle::Callout)
.border_1()
.border_color(widgets::RING_SLOT)
.cursor_pointer()
.child(SharedString::from(page.to_string()));
if current {
button
.bg(theme.accent)
.font_weight(gpui::FontWeight::MEDIUM)
.text_color(theme.on_accent)
} else {
button
.text_color(theme.text_muted)
.hover(|s| s.bg(theme.element_hover).text_color(theme.text))
}
}
pub fn ellipsis(theme: &Theme) -> gpui::Div {
div()
.w(px(BUTTON))
.h(px(BUTTON))
.flex()
.items_center()
.justify_center()
.text_style(TextStyle::Callout)
.text_color(theme.text_faint)
.child(SharedString::from("…"))
}
pub fn step(theme: &Theme, icon: impl Into<Icon>, enabled: bool) -> gpui::Div {
let step = div()
.size(px(BUTTON))
.rounded(px(7.0))
.flex()
.items_center()
.justify_center()
.border_1()
.border_color(widgets::RING_SLOT);
if enabled {
step.cursor_pointer()
.hover(|s| s.bg(theme.element_hover))
.child(icons::icon(icon).size(px(14.0)).text_color(theme.text))
} else {
step.child(
icons::icon(icon)
.size(px(14.0))
.text_color(theme.text_faint),
)
}
}