93 lines
2.6 KiB
Rust
93 lines
2.6 KiB
Rust
// src/state/app/buffer.rs
|
|
|
|
/// Represents the distinct views or "buffers" the user can navigate.
|
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
pub enum AppView {
|
|
Intro,
|
|
Login,
|
|
Register,
|
|
Admin,
|
|
Form(String),
|
|
Scratch,
|
|
}
|
|
|
|
impl AppView {
|
|
/// Returns the display name for the view.
|
|
pub fn display_name(&self) -> &str {
|
|
match self {
|
|
AppView::Intro => "Intro",
|
|
AppView::Login => "Login",
|
|
AppView::Register => "Register",
|
|
AppView::Admin => "Admin Panel",
|
|
AppView::Form(name) => name.as_str(),
|
|
AppView::Scratch => "*scratch*",
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Holds the state related to buffer management (navigation history).
|
|
#[derive(Debug, Clone)]
|
|
pub struct BufferState {
|
|
pub history: Vec<AppView>,
|
|
pub active_index: usize,
|
|
}
|
|
|
|
impl Default for BufferState {
|
|
fn default() -> Self {
|
|
Self {
|
|
history: vec![AppView::Intro], // Start with Intro view
|
|
active_index: 0,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl BufferState {
|
|
/// Updates the buffer history and active index.
|
|
/// If the view already exists, it sets it as active.
|
|
/// Otherwise, it adds the new view and makes it active.
|
|
pub fn update_history(&mut self, view: AppView) {
|
|
let existing_pos = self.history.iter().position(|v| v == &view);
|
|
|
|
match existing_pos {
|
|
Some(pos) => {
|
|
self.active_index = pos;
|
|
}
|
|
None => {
|
|
self.history.push(view.clone());
|
|
self.active_index = self.history.len() - 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Gets the currently active view.
|
|
pub fn get_active_view(&self) -> Option<&AppView> {
|
|
self.history.get(self.active_index)
|
|
}
|
|
|
|
/// Removes the currently active buffer from the history, unless it's the Intro buffer.
|
|
/// Sets the new active buffer to the one preceding the closed one.
|
|
/// # Returns
|
|
/// * `true` if a non-Intro buffer was closed.
|
|
/// * `false` if the active buffer was Intro or only Intro remained.
|
|
pub fn close_active_buffer(&mut self) -> bool {
|
|
let current_index = self.active_index;
|
|
|
|
// Rule 1: Cannot close Intro buffer.
|
|
if matches!(self.history.get(current_index), Some(AppView::Intro)) {
|
|
return false;
|
|
}
|
|
|
|
// Rule 2: Cannot close if only Intro would remain (or already remains).
|
|
// This check implicitly covers the case where len <= 1.
|
|
if self.history.len() <= 1 {
|
|
return false;
|
|
}
|
|
|
|
self.history.remove(current_index);
|
|
self.active_index = current_index.saturating_sub(1).min(self.history.len() - 1);
|
|
|
|
true
|
|
}
|
|
}
|
|
|