use crate::tui::ui::SidebarSections;
use std::path::PathBuf;
pub use crate::config::{SidebarOrientation, SidebarPosition};
pub const SIDEBAR_MIN_WIDTH: u16 = 120;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ResolvedSidebarLayout {
Hidden,
SideBySide { sidebar_left: bool },
Stacked,
}
impl ResolvedSidebarLayout {
pub fn split_percentages(self) -> Option<(u16, u16)> {
match self {
ResolvedSidebarLayout::Hidden => None,
ResolvedSidebarLayout::SideBySide { .. } => Some((55, 45)),
ResolvedSidebarLayout::Stacked => Some((42, 58)),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum SidebarMode {
Commits,
Stashes,
}
impl SidebarMode {
pub fn label(self) -> &'static str {
match self {
SidebarMode::Commits => "commits",
SidebarMode::Stashes => "stashes",
}
}
}
#[derive(Debug)]
pub struct SidebarState {
pub open: bool,
pub position: SidebarPosition,
pub orientation: SidebarOrientation,
pub focused: bool,
pub scroll: u16,
pub max_scroll: u16,
pub cache: Option<((PathBuf, SidebarMode), SidebarSections)>,
pub mode: SidebarMode,
}
impl Default for SidebarState {
fn default() -> Self {
Self::new()
}
}
impl SidebarState {
pub fn new() -> Self {
Self {
open: true,
position: SidebarPosition::default(),
orientation: SidebarOrientation::default(),
focused: false,
scroll: 0,
max_scroll: 0,
cache: None,
mode: SidebarMode::Commits,
}
}
pub fn resolve_layout(&self, width: u16) -> ResolvedSidebarLayout {
if !self.open {
return ResolvedSidebarLayout::Hidden;
}
let side_by_side = ResolvedSidebarLayout::SideBySide {
sidebar_left: self.position.is_left(),
};
match self.orientation {
SidebarOrientation::SideBySide => side_by_side,
SidebarOrientation::Stacked => ResolvedSidebarLayout::Stacked,
SidebarOrientation::Auto => {
if width >= SIDEBAR_MIN_WIDTH {
side_by_side
} else {
ResolvedSidebarLayout::Stacked
}
}
}
}
pub fn cycle_orientation(&mut self) {
self.orientation = self.orientation.next();
}
pub fn toggle_position(&mut self) {
self.position = match self.position {
SidebarPosition::Left => SidebarPosition::Right,
SidebarPosition::Right => SidebarPosition::Left,
};
}
pub fn cycle_mode(&mut self) {
self.mode = match self.mode {
SidebarMode::Commits => SidebarMode::Stashes,
SidebarMode::Stashes => SidebarMode::Commits,
};
self.scroll = 0;
self.cache = None;
}
pub fn on_navigation(&mut self) {
self.scroll = 0;
self.cache = None;
}
pub fn invalidate(&mut self) {
self.cache = None;
}
pub fn scroll_down(&mut self) {
self.scroll = self.scroll.saturating_add(1).min(self.max_scroll);
}
pub fn scroll_up(&mut self) {
self.scroll = self.scroll.saturating_sub(1);
}
pub fn toggle_open(&mut self) {
self.open = !self.open;
if !self.open {
self.focused = false;
}
}
pub fn toggle_focus(&mut self) {
if !self.open {
return;
}
self.focused = !self.focused;
}
pub fn focus_table(&mut self) {
self.focused = false;
}
pub fn focus_panel(&mut self) {
self.open = true;
self.focused = true;
}
}