This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
use doux::audio::AudioDeviceInfo;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use super::CyclicEnum;
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Default)]
|
||||
pub enum RefreshRate {
|
||||
#[default]
|
||||
@@ -128,6 +130,10 @@ pub enum EngineSection {
|
||||
Samples,
|
||||
}
|
||||
|
||||
impl CyclicEnum for EngineSection {
|
||||
const VARIANTS: &'static [Self] = &[Self::Devices, Self::Settings, Self::Samples];
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Default)]
|
||||
pub enum DeviceKind {
|
||||
#[default]
|
||||
@@ -145,26 +151,14 @@ pub enum SettingKind {
|
||||
Lookahead,
|
||||
}
|
||||
|
||||
impl SettingKind {
|
||||
pub fn next(self) -> Self {
|
||||
match self {
|
||||
Self::Channels => Self::BufferSize,
|
||||
Self::BufferSize => Self::Polyphony,
|
||||
Self::Polyphony => Self::Nudge,
|
||||
Self::Nudge => Self::Lookahead,
|
||||
Self::Lookahead => Self::Channels,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn prev(self) -> Self {
|
||||
match self {
|
||||
Self::Channels => Self::Lookahead,
|
||||
Self::BufferSize => Self::Channels,
|
||||
Self::Polyphony => Self::BufferSize,
|
||||
Self::Nudge => Self::Polyphony,
|
||||
Self::Lookahead => Self::Nudge,
|
||||
}
|
||||
}
|
||||
impl CyclicEnum for SettingKind {
|
||||
const VARIANTS: &'static [Self] = &[
|
||||
Self::Channels,
|
||||
Self::BufferSize,
|
||||
Self::Polyphony,
|
||||
Self::Nudge,
|
||||
Self::Lookahead,
|
||||
];
|
||||
}
|
||||
|
||||
pub struct Metrics {
|
||||
@@ -242,19 +236,11 @@ impl AudioSettings {
|
||||
}
|
||||
|
||||
pub fn next_section(&mut self) {
|
||||
self.section = match self.section {
|
||||
EngineSection::Devices => EngineSection::Settings,
|
||||
EngineSection::Settings => EngineSection::Samples,
|
||||
EngineSection::Samples => EngineSection::Devices,
|
||||
};
|
||||
self.section = self.section.next();
|
||||
}
|
||||
|
||||
pub fn prev_section(&mut self) {
|
||||
self.section = match self.section {
|
||||
EngineSection::Devices => EngineSection::Samples,
|
||||
EngineSection::Settings => EngineSection::Devices,
|
||||
EngineSection::Samples => EngineSection::Settings,
|
||||
};
|
||||
self.section = self.section.prev();
|
||||
}
|
||||
|
||||
pub fn current_output_device_index(&self) -> usize {
|
||||
|
||||
@@ -3,12 +3,6 @@ use std::ops::RangeInclusive;
|
||||
|
||||
use cagire_ratatui::Editor;
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||
pub enum Focus {
|
||||
Sequencer,
|
||||
Editor,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||
pub enum PatternField {
|
||||
Length,
|
||||
@@ -51,7 +45,6 @@ pub struct EditorContext {
|
||||
pub bank: usize,
|
||||
pub pattern: usize,
|
||||
pub step: usize,
|
||||
pub focus: Focus,
|
||||
pub editor: Editor,
|
||||
pub selection_anchor: Option<usize>,
|
||||
pub copied_steps: Option<CopiedSteps>,
|
||||
@@ -101,7 +94,6 @@ impl Default for EditorContext {
|
||||
bank: 0,
|
||||
pattern: 0,
|
||||
step: 0,
|
||||
focus: Focus::Sequencer,
|
||||
editor: Editor::new(),
|
||||
selection_anchor: None,
|
||||
copied_steps: None,
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
pub trait CyclicEnum: Sized + Copy + PartialEq + 'static {
|
||||
const VARIANTS: &'static [Self];
|
||||
|
||||
fn next(self) -> Self {
|
||||
let pos = Self::VARIANTS.iter().position(|v| *v == self).unwrap_or(0);
|
||||
Self::VARIANTS[(pos + 1) % Self::VARIANTS.len()]
|
||||
}
|
||||
|
||||
fn prev(self) -> Self {
|
||||
let len = Self::VARIANTS.len();
|
||||
let pos = Self::VARIANTS.iter().position(|v| *v == self).unwrap_or(0);
|
||||
Self::VARIANTS[(pos + len - 1) % len]
|
||||
}
|
||||
}
|
||||
|
||||
pub mod audio;
|
||||
pub mod color_scheme;
|
||||
pub mod editor;
|
||||
@@ -14,10 +29,12 @@ pub mod ui;
|
||||
|
||||
pub use audio::{AudioSettings, DeviceKind, EngineSection, Metrics, SettingKind};
|
||||
pub use color_scheme::ColorScheme;
|
||||
pub use options::{OptionsFocus, OptionsState};
|
||||
pub use editor::{CopiedStepData, CopiedSteps, EditorContext, Focus, PatternField, PatternPropsField, StackCache};
|
||||
pub use editor::{
|
||||
CopiedStepData, CopiedSteps, EditorContext, PatternField, PatternPropsField, StackCache,
|
||||
};
|
||||
pub use live_keys::LiveKeyState;
|
||||
pub use modal::Modal;
|
||||
pub use options::{OptionsFocus, OptionsState};
|
||||
pub use panel::{PanelFocus, PanelState, SidePanel};
|
||||
pub use patterns_nav::{PatternsColumn, PatternsNav};
|
||||
pub use playback::{PlaybackState, StagedChange};
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
use super::CyclicEnum;
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Default)]
|
||||
pub enum OptionsFocus {
|
||||
#[default]
|
||||
@@ -21,6 +23,29 @@ pub enum OptionsFocus {
|
||||
MidiInput3,
|
||||
}
|
||||
|
||||
impl CyclicEnum for OptionsFocus {
|
||||
const VARIANTS: &'static [Self] = &[
|
||||
Self::ColorScheme,
|
||||
Self::RefreshRate,
|
||||
Self::RuntimeHighlight,
|
||||
Self::ShowScope,
|
||||
Self::ShowSpectrum,
|
||||
Self::ShowCompletion,
|
||||
Self::FlashBrightness,
|
||||
Self::LinkEnabled,
|
||||
Self::StartStopSync,
|
||||
Self::Quantum,
|
||||
Self::MidiOutput0,
|
||||
Self::MidiOutput1,
|
||||
Self::MidiOutput2,
|
||||
Self::MidiOutput3,
|
||||
Self::MidiInput0,
|
||||
Self::MidiInput1,
|
||||
Self::MidiInput2,
|
||||
Self::MidiInput3,
|
||||
];
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct OptionsState {
|
||||
pub focus: OptionsFocus,
|
||||
@@ -28,48 +53,10 @@ pub struct OptionsState {
|
||||
|
||||
impl OptionsState {
|
||||
pub fn next_focus(&mut self) {
|
||||
self.focus = match self.focus {
|
||||
OptionsFocus::ColorScheme => OptionsFocus::RefreshRate,
|
||||
OptionsFocus::RefreshRate => OptionsFocus::RuntimeHighlight,
|
||||
OptionsFocus::RuntimeHighlight => OptionsFocus::ShowScope,
|
||||
OptionsFocus::ShowScope => OptionsFocus::ShowSpectrum,
|
||||
OptionsFocus::ShowSpectrum => OptionsFocus::ShowCompletion,
|
||||
OptionsFocus::ShowCompletion => OptionsFocus::FlashBrightness,
|
||||
OptionsFocus::FlashBrightness => OptionsFocus::LinkEnabled,
|
||||
OptionsFocus::LinkEnabled => OptionsFocus::StartStopSync,
|
||||
OptionsFocus::StartStopSync => OptionsFocus::Quantum,
|
||||
OptionsFocus::Quantum => OptionsFocus::MidiOutput0,
|
||||
OptionsFocus::MidiOutput0 => OptionsFocus::MidiOutput1,
|
||||
OptionsFocus::MidiOutput1 => OptionsFocus::MidiOutput2,
|
||||
OptionsFocus::MidiOutput2 => OptionsFocus::MidiOutput3,
|
||||
OptionsFocus::MidiOutput3 => OptionsFocus::MidiInput0,
|
||||
OptionsFocus::MidiInput0 => OptionsFocus::MidiInput1,
|
||||
OptionsFocus::MidiInput1 => OptionsFocus::MidiInput2,
|
||||
OptionsFocus::MidiInput2 => OptionsFocus::MidiInput3,
|
||||
OptionsFocus::MidiInput3 => OptionsFocus::ColorScheme,
|
||||
};
|
||||
self.focus = self.focus.next();
|
||||
}
|
||||
|
||||
pub fn prev_focus(&mut self) {
|
||||
self.focus = match self.focus {
|
||||
OptionsFocus::ColorScheme => OptionsFocus::MidiInput3,
|
||||
OptionsFocus::RefreshRate => OptionsFocus::ColorScheme,
|
||||
OptionsFocus::RuntimeHighlight => OptionsFocus::RefreshRate,
|
||||
OptionsFocus::ShowScope => OptionsFocus::RuntimeHighlight,
|
||||
OptionsFocus::ShowSpectrum => OptionsFocus::ShowScope,
|
||||
OptionsFocus::ShowCompletion => OptionsFocus::ShowSpectrum,
|
||||
OptionsFocus::FlashBrightness => OptionsFocus::ShowCompletion,
|
||||
OptionsFocus::LinkEnabled => OptionsFocus::FlashBrightness,
|
||||
OptionsFocus::StartStopSync => OptionsFocus::LinkEnabled,
|
||||
OptionsFocus::Quantum => OptionsFocus::StartStopSync,
|
||||
OptionsFocus::MidiOutput0 => OptionsFocus::Quantum,
|
||||
OptionsFocus::MidiOutput1 => OptionsFocus::MidiOutput0,
|
||||
OptionsFocus::MidiOutput2 => OptionsFocus::MidiOutput1,
|
||||
OptionsFocus::MidiOutput3 => OptionsFocus::MidiOutput2,
|
||||
OptionsFocus::MidiInput0 => OptionsFocus::MidiOutput3,
|
||||
OptionsFocus::MidiInput1 => OptionsFocus::MidiInput0,
|
||||
OptionsFocus::MidiInput2 => OptionsFocus::MidiInput1,
|
||||
OptionsFocus::MidiInput3 => OptionsFocus::MidiInput2,
|
||||
};
|
||||
self.focus = self.focus.prev();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ pub struct UiState {
|
||||
pub help_search_query: String,
|
||||
pub dict_focus: DictFocus,
|
||||
pub dict_category: usize,
|
||||
pub dict_scroll: usize,
|
||||
pub dict_scrolls: Vec<usize>,
|
||||
pub dict_search_query: String,
|
||||
pub dict_search_active: bool,
|
||||
pub show_title: bool,
|
||||
@@ -67,7 +67,7 @@ impl Default for UiState {
|
||||
help_search_query: String::new(),
|
||||
dict_focus: DictFocus::default(),
|
||||
dict_category: 0,
|
||||
dict_scroll: 0,
|
||||
dict_scrolls: vec![0; crate::views::dict_view::category_count()],
|
||||
dict_search_query: String::new(),
|
||||
dict_search_active: false,
|
||||
show_title: true,
|
||||
@@ -91,6 +91,14 @@ impl UiState {
|
||||
&mut self.help_scrolls[self.help_topic]
|
||||
}
|
||||
|
||||
pub fn dict_scroll(&self) -> usize {
|
||||
self.dict_scrolls[self.dict_category]
|
||||
}
|
||||
|
||||
pub fn dict_scroll_mut(&mut self) -> &mut usize {
|
||||
&mut self.dict_scrolls[self.dict_category]
|
||||
}
|
||||
|
||||
pub fn flash(&mut self, msg: &str, duration_ms: u64, kind: FlashKind) {
|
||||
self.status_message = Some(msg.to_string());
|
||||
self.flash_until = Some(Instant::now() + Duration::from_millis(duration_ms));
|
||||
|
||||
Reference in New Issue
Block a user