use crate::field::Field;
use crate::submit::{SubmitFn, SubmitOutcome};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum FormMode {
Normal,
Insert,
}
#[derive(Debug)]
pub enum FormEvent {
Changed,
Cancelled,
Submitted(SubmitOutcome),
ValidationFailed,
}
pub struct Form {
pub title: Option<String>,
pub fields: Vec<Field>,
pub mode: FormMode,
pub(crate) focused: usize,
pub(crate) submit: Option<SubmitFn>,
pub(crate) dirty_gen: u64,
pub(crate) pending_g: bool,
}
impl Form {
pub fn new() -> Self {
Self {
title: None,
fields: Vec::new(),
mode: FormMode::Normal,
focused: 0,
submit: None,
dirty_gen: 0,
pending_g: false,
}
}
pub fn with_title(mut self, title: impl Into<String>) -> Self {
self.title = Some(title.into());
self
}
pub fn with_field(mut self, field: Field) -> Self {
self.fields.push(field);
self
}
pub fn with_submit(mut self, submit: SubmitFn) -> Self {
self.submit = Some(submit);
self
}
pub fn focused(&self) -> usize {
self.focused
}
pub fn focused_field(&self) -> Option<&Field> {
self.fields.get(self.focused)
}
pub fn focused_field_mut(&mut self) -> Option<&mut Field> {
self.fields.get_mut(self.focused)
}
pub fn set_focus(&mut self, index: usize) {
if index < self.fields.len() {
self.focused = index;
self.dirty_gen = self.dirty_gen.wrapping_add(1);
}
}
pub fn dirty_gen(&self) -> u64 {
let mut sum = self.dirty_gen;
for field in &self.fields {
match field {
Field::SingleLineText(f) | Field::MultiLineText(f) => {
sum = sum.wrapping_add(f.editor.buffer().dirty_gen());
}
_ => {}
}
}
sum
}
pub(crate) fn bump_dirty(&mut self) {
self.dirty_gen = self.dirty_gen.wrapping_add(1);
}
}
impl Default for Form {
fn default() -> Self {
Self::new()
}
}