use std::cell::Cell; use std::ops::RangeInclusive; use cagire_ratatui::Editor; #[derive(Clone, Copy, PartialEq, Eq, Default)] pub enum EditorTarget { #[default] Step, Prelude, BankPrelude, } #[derive(Clone, Copy, PartialEq, Eq)] pub enum PatternField { Length, Speed, } #[derive(Clone, Copy, PartialEq, Eq)] pub enum ScriptField { Speed, Length, } #[derive(Clone, Copy, PartialEq, Eq, Default)] pub enum PatternPropsField { #[default] Name, Description, Length, Speed, Quantization, SyncMode, FollowUp, ChainBank, ChainPattern, } impl PatternPropsField { pub fn next(&self, follow_up_is_chain: bool) -> Self { match self { Self::Name => Self::Description, Self::Description => Self::Length, Self::Length => Self::Speed, Self::Speed => Self::Quantization, Self::Quantization => Self::SyncMode, Self::SyncMode => Self::FollowUp, Self::FollowUp if follow_up_is_chain => Self::ChainBank, Self::FollowUp => Self::FollowUp, Self::ChainBank => Self::ChainPattern, Self::ChainPattern => Self::ChainPattern, } } pub fn prev(&self, follow_up_is_chain: bool) -> Self { match self { Self::Name => Self::Name, Self::Description => Self::Name, Self::Length => Self::Description, Self::Speed => Self::Length, Self::Quantization => Self::Speed, Self::SyncMode => Self::Quantization, Self::FollowUp => Self::SyncMode, Self::ChainBank => Self::FollowUp, Self::ChainPattern if follow_up_is_chain => Self::ChainBank, Self::ChainPattern => Self::FollowUp, } } } #[derive(Clone, Copy, PartialEq, Eq, Default)] pub enum EuclideanField { #[default] Pulses, Steps, Rotation, } impl EuclideanField { pub fn next(&self) -> Self { match self { Self::Pulses => Self::Steps, Self::Steps => Self::Rotation, Self::Rotation => Self::Rotation, } } pub fn prev(&self) -> Self { match self { Self::Pulses => Self::Pulses, Self::Steps => Self::Pulses, Self::Rotation => Self::Steps, } } } pub struct EditorContext { pub bank: usize, pub pattern: usize, pub step: usize, pub editor: Editor, pub selection_anchor: Option, pub copied_steps: Option, pub target: EditorTarget, pub steps_per_page: Cell, pub mouse_selecting: bool, } #[derive(Clone)] pub struct CopiedSteps { pub bank: usize, pub pattern: usize, pub steps: Vec, } #[derive(Clone)] pub struct CopiedStepData { pub script: String, pub active: bool, pub source: Option, pub original_index: usize, pub name: Option, } impl EditorContext { pub fn selection_range(&self) -> Option> { let anchor = self.selection_anchor?; let a = anchor.min(self.step); let b = anchor.max(self.step); Some(a..=b) } pub fn clear_selection(&mut self) { self.selection_anchor = None; } } impl Default for EditorContext { fn default() -> Self { Self { bank: 0, pattern: 0, step: 0, editor: Editor::new(), selection_anchor: None, copied_steps: None, target: EditorTarget::default(), steps_per_page: Cell::new(32), mouse_selecting: false, } } } pub struct ScriptEditorState { pub editor: Editor, pub dirty: bool, pub focused: bool, pub mouse_selecting: bool, } impl Default for ScriptEditorState { fn default() -> Self { Self { editor: Editor::new(), dirty: false, focused: true, mouse_selecting: false, } } }