use super::MAX_SHOWN;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Split {
H,
V,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct DetailLayout {
pub shown: Vec<String>,
pub split: Split,
pub focus: usize,
}
impl DetailLayout {
pub(super) fn solo(record_id: String) -> Self {
Self {
shown: vec![record_id],
split: Split::H,
focus: 0,
}
}
pub(super) fn add(&mut self, record_id: String, split: Split) {
self.split = split;
if let Some(i) = self.shown.iter().position(|r| r == &record_id) {
self.focus = i;
return;
}
if self.shown.len() >= MAX_SHOWN {
return;
}
self.shown.push(record_id);
self.focus = self.shown.len() - 1;
}
pub(super) fn remove_focused(&mut self) {
if self.shown.len() > 1 {
self.shown.remove(self.focus);
if self.focus >= self.shown.len() {
self.focus = self.shown.len() - 1;
}
}
}
pub(super) fn prune(&mut self, record_id: &str) {
self.shown.retain(|r| r != record_id);
if self.focus >= self.shown.len() {
self.focus = self.shown.len().saturating_sub(1);
}
}
pub(super) fn focused_id(&self) -> Option<&str> {
self.shown.get(self.focus).map(String::as_str)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ClickTarget {
ToggleSessions,
ToggleSubagents,
SessionRow(usize),
RailRow(usize),
NewSession,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ClickZone {
pub x: u16,
pub y: u16,
pub w: u16,
pub h: u16,
pub target: ClickTarget,
}
impl ClickZone {
pub(super) fn contains(&self, col: u16, row: u16) -> bool {
col >= self.x && col < self.x + self.w && row >= self.y && row < self.y + self.h
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PtyArea {
pub record_id: String,
pub x: u16,
pub y: u16,
pub cols: u16,
pub rows: u16,
}
impl PtyArea {
pub fn contains(&self, col: u16, row: u16) -> bool {
col >= self.x && col < self.x + self.cols && row >= self.y && row < self.y + self.rows
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn pty_area_contains_is_half_open() {
let area = PtyArea {
record_id: "rec".into(),
x: 2,
y: 1,
cols: 4,
rows: 3,
};
assert!(area.contains(2, 1), "top-left inclusive");
assert!(area.contains(5, 3), "bottom-right inclusive");
assert!(!area.contains(6, 3), "one past the last column is outside");
assert!(!area.contains(5, 4), "one past the last row is outside");
assert!(!area.contains(1, 1), "the border column is outside");
}
}