mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 11:46:41 +01:00
PhrasesMode -> PhraseListMode
This commit is contained in:
parent
a7ff74e27c
commit
69faadac2b
7 changed files with 65 additions and 62 deletions
|
|
@ -5,6 +5,10 @@ pub trait HasPhrases {
|
|||
fn phrases_mut (&mut self) -> &mut Vec<Arc<RwLock<Phrase>>>;
|
||||
}
|
||||
|
||||
pub trait HasPhrase {
|
||||
fn phrase (&self) -> &Arc<RwLock<Phrase>>;
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub enum PhrasePoolCommand {
|
||||
Add(usize, Phrase),
|
||||
|
|
|
|||
|
|
@ -168,6 +168,21 @@ impl HasPhrases for ArrangerTui {
|
|||
}
|
||||
}
|
||||
|
||||
impl HasPhraseList for ArrangerTui {
|
||||
fn phrases_focused (&self) -> bool {
|
||||
self.focused() == ArrangerFocus::Phrases
|
||||
}
|
||||
fn phrases_entered (&self) -> bool {
|
||||
self.entered() && self.phrases_focused()
|
||||
}
|
||||
fn phrases_mode (&self) -> &Option<PhraseListMode> {
|
||||
&self.phrases.mode
|
||||
}
|
||||
fn phrase_index (&self) -> usize {
|
||||
self.phrases.phrase.load(Ordering::Relaxed)
|
||||
}
|
||||
}
|
||||
|
||||
impl HasEditor for ArrangerTui {
|
||||
fn editor (&self) -> &PhraseEditorModel {
|
||||
&self.editor
|
||||
|
|
|
|||
|
|
@ -148,7 +148,7 @@ impl HasPhraseList for SequencerTui {
|
|||
fn phrases_entered (&self) -> bool {
|
||||
true
|
||||
}
|
||||
fn phrases_mode (&self) -> &Option<PhrasesMode> {
|
||||
fn phrases_mode (&self) -> &Option<PhraseListMode> {
|
||||
&self.phrases.mode
|
||||
}
|
||||
fn phrase_index (&self) -> usize {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use crate::*;
|
||||
use KeyCode::{Up, Down, Right, Left, Enter, Esc, Char, Backspace};
|
||||
use FileBrowserCommand::*;
|
||||
use super::phrase_list::PhrasesMode::{Import, Export};
|
||||
use super::phrase_list::PhraseListMode::{Import, Export};
|
||||
|
||||
/// Browses for phrase to import/export
|
||||
#[derive(Debug, Clone)]
|
||||
|
|
@ -121,12 +121,12 @@ impl Command<PhraseListModel> for FileBrowserCommand {
|
|||
},
|
||||
_ => todo!(),
|
||||
},
|
||||
Some(PhrasesMode::Export(index, ref mut browser)) => match self {
|
||||
Some(PhraseListMode::Export(index, ref mut browser)) => match self {
|
||||
Cancel => {
|
||||
*mode = None;
|
||||
},
|
||||
Chdir(cwd) => {
|
||||
*mode = Some(PhrasesMode::Export(*index, FileBrowser::new(Some(cwd))?));
|
||||
*mode = Some(PhraseListMode::Export(*index, FileBrowser::new(Some(cwd))?));
|
||||
},
|
||||
Select(index) => {
|
||||
browser.index = index;
|
||||
|
|
@ -141,7 +141,7 @@ impl Command<PhraseListModel> for FileBrowserCommand {
|
|||
|
||||
impl InputToCommand<Tui, PhraseListModel> for FileBrowserCommand {
|
||||
fn input_to_command (state: &PhraseListModel, from: &TuiInput) -> Option<Self> {
|
||||
if let Some(PhrasesMode::Import(_index, browser)) = state.phrases_mode() {
|
||||
if let Some(PhraseListMode::Import(_index, browser)) = state.phrases_mode() {
|
||||
Some(match from.event() {
|
||||
key!(Up) => Select(
|
||||
browser.index.overflowing_sub(1).0.min(browser.len().saturating_sub(1))
|
||||
|
|
@ -157,7 +157,7 @@ impl InputToCommand<Tui, PhraseListModel> for FileBrowserCommand {
|
|||
key!(Esc) => Self::Cancel,
|
||||
_ => return None
|
||||
})
|
||||
} else if let Some(PhrasesMode::Export(_index, browser)) = state.phrases_mode() {
|
||||
} else if let Some(PhraseListMode::Export(_index, browser)) = state.phrases_mode() {
|
||||
Some(match from.event() {
|
||||
key!(Up) => Select(browser.index.overflowing_sub(1).0.min(browser.len())),
|
||||
key!(Down) => Select(browser.index.saturating_add(1) % browser.len()),
|
||||
|
|
@ -177,7 +177,7 @@ impl InputToCommand<Tui, PhraseListModel> for FileBrowserCommand {
|
|||
|
||||
impl InputToCommand<Tui, PhraseListModel> for PhraseLengthCommand {
|
||||
fn input_to_command (state: &PhraseListModel, from: &TuiInput) -> Option<Self> {
|
||||
if let Some(PhrasesMode::Length(_, length, _)) = state.phrases_mode() {
|
||||
if let Some(PhraseListMode::Length(_, length, _)) = state.phrases_mode() {
|
||||
Some(match from.event() {
|
||||
key!(Up) => Self::Inc,
|
||||
key!(Down) => Self::Dec,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use crate::*;
|
||||
use super::phrase_list::{PhraseListModel, PhrasesMode};
|
||||
use super::phrase_list::{PhraseListModel, PhraseListMode};
|
||||
use PhraseLengthFocus::*;
|
||||
use PhraseLengthCommand::*;
|
||||
|
||||
|
|
@ -75,13 +75,13 @@ render!(|self: PhraseLength|{
|
|||
let ticks = ||self.ticks_string();
|
||||
row!(move|add|match self.focus {
|
||||
None =>
|
||||
add(&row!([" ", bars(), "B", beats(), "b", ticks(), "T"])),
|
||||
add(&row!([" ", bars(), ".", beats(), ".", ticks()])),
|
||||
Some(PhraseLengthFocus::Bar) =>
|
||||
add(&row!(["[", bars(), "]", beats(), "b", ticks(), "T"])),
|
||||
add(&row!(["[", bars(), "]", beats(), ".", ticks()])),
|
||||
Some(PhraseLengthFocus::Beat) =>
|
||||
add(&row!([" ", bars(), "[", beats(), "]", ticks(), "T"])),
|
||||
add(&row!([" ", bars(), "[", beats(), "]", ticks()])),
|
||||
Some(PhraseLengthFocus::Tick) =>
|
||||
add(&row!([" ", bars(), "B", beats(), "[", ticks(), "]"])),
|
||||
add(&row!([" ", bars(), ".", beats(), "[", ticks()])),
|
||||
})
|
||||
});
|
||||
|
||||
|
|
@ -99,7 +99,7 @@ pub enum PhraseLengthCommand {
|
|||
impl Command<PhraseListModel> for PhraseLengthCommand {
|
||||
fn execute (self, state: &mut PhraseListModel) -> Perhaps<Self> {
|
||||
match state.phrases_mode_mut().clone() {
|
||||
Some(PhrasesMode::Length(phrase, ref mut length, ref mut focus)) => match self {
|
||||
Some(PhraseListMode::Length(phrase, ref mut length, ref mut focus)) => match self {
|
||||
Cancel => { *state.phrases_mode_mut() = None; },
|
||||
Prev => { focus.prev() },
|
||||
Next => { focus.next() },
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
use super::*;
|
||||
use crate::{
|
||||
*,
|
||||
api::PhrasePoolCommand as Pool,
|
||||
tui::{
|
||||
phrase_rename::PhraseRenameCommand as Rename,
|
||||
|
|
@ -16,9 +15,22 @@ pub struct PhraseListModel {
|
|||
/// Selected phrase
|
||||
pub(crate) phrase: AtomicUsize,
|
||||
/// Scroll offset
|
||||
pub(crate) scroll: usize,
|
||||
pub scroll: usize,
|
||||
/// Mode switch
|
||||
pub(crate) mode: Option<PhrasesMode>,
|
||||
pub(crate) mode: Option<PhraseListMode>,
|
||||
}
|
||||
|
||||
/// Modes for phrase pool
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum PhraseListMode {
|
||||
/// Renaming a pattern
|
||||
Rename(usize, String),
|
||||
/// Editing the length of a pattern
|
||||
Length(usize, usize, PhraseLengthFocus),
|
||||
/// Load phrase from disk
|
||||
Import(usize, FileBrowser),
|
||||
/// Save phrase to disk
|
||||
Export(usize, FileBrowser),
|
||||
}
|
||||
|
||||
impl Default for PhraseListModel {
|
||||
|
|
@ -42,56 +54,28 @@ impl PhraseListModel {
|
|||
pub(crate) fn set_phrase_index (&self, value: usize) {
|
||||
self.phrase.store(value, Ordering::Relaxed);
|
||||
}
|
||||
pub(crate) fn phrases_mode (&self) -> &Option<PhrasesMode> {
|
||||
pub(crate) fn phrases_mode (&self) -> &Option<PhraseListMode> {
|
||||
&self.mode
|
||||
}
|
||||
pub(crate) fn phrases_mode_mut (&mut self) -> &mut Option<PhrasesMode> {
|
||||
pub(crate) fn phrases_mode_mut (&mut self) -> &mut Option<PhraseListMode> {
|
||||
&mut self.mode
|
||||
}
|
||||
}
|
||||
|
||||
/// Modes for phrase pool
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum PhrasesMode {
|
||||
/// Renaming a pattern
|
||||
Rename(usize, String),
|
||||
/// Editing the length of a pattern
|
||||
Length(usize, usize, PhraseLengthFocus),
|
||||
/// Load phrase from disk
|
||||
Import(usize, FileBrowser),
|
||||
/// Save phrase to disk
|
||||
Export(usize, FileBrowser),
|
||||
}
|
||||
|
||||
pub trait HasPhraseList: HasPhrases {
|
||||
fn phrases_focused (&self) -> bool;
|
||||
fn phrases_entered (&self) -> bool;
|
||||
fn phrases_mode (&self) -> &Option<PhrasesMode>;
|
||||
fn phrases_mode (&self) -> &Option<PhraseListMode>;
|
||||
fn phrase_index (&self) -> usize;
|
||||
}
|
||||
|
||||
impl HasPhraseList for ArrangerTui {
|
||||
fn phrases_focused (&self) -> bool {
|
||||
self.focused() == ArrangerFocus::Phrases
|
||||
}
|
||||
fn phrases_entered (&self) -> bool {
|
||||
self.entered() && self.phrases_focused()
|
||||
}
|
||||
fn phrases_mode (&self) -> &Option<PhrasesMode> {
|
||||
&self.phrases.mode
|
||||
}
|
||||
fn phrase_index (&self) -> usize {
|
||||
self.phrases.phrase.load(Ordering::Relaxed)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct PhraseListView<'a> {
|
||||
pub(crate) title: &'static str,
|
||||
pub(crate) focused: bool,
|
||||
pub(crate) entered: bool,
|
||||
pub(crate) phrases: &'a Vec<Arc<RwLock<Phrase>>>,
|
||||
pub(crate) index: usize,
|
||||
pub(crate) mode: &'a Option<PhrasesMode>
|
||||
pub(crate) mode: &'a Option<PhraseListMode>
|
||||
}
|
||||
|
||||
impl<'a, T: HasPhraseList> From<&'a T> for PhraseListView<'a> {
|
||||
|
|
@ -117,13 +101,13 @@ render!(|self: PhraseListView<'a>|{
|
|||
Tui::bg(bg, lay!(move|add|{
|
||||
//add(&Lozenge(Style::default().bg(border_bg).fg(border_color)))?;
|
||||
add(&Tui::inset_xy(0, 1, Tui::fill_xy(col!(move|add|match mode {
|
||||
Some(PhrasesMode::Import(_, ref file_picker)) => add(file_picker),
|
||||
Some(PhrasesMode::Export(_, ref file_picker)) => add(file_picker),
|
||||
Some(PhraseListMode::Import(_, ref file_picker)) => add(file_picker),
|
||||
Some(PhraseListMode::Export(_, ref file_picker)) => add(file_picker),
|
||||
_ => Ok(for (i, phrase) in phrases.iter().enumerate() {
|
||||
add(&lay!(|add|{
|
||||
let Phrase { ref name, color, length, .. } = *phrase.read().unwrap();
|
||||
let mut length = PhraseLength::new(length, None);
|
||||
if let Some(PhrasesMode::Length(phrase, new_length, focus)) = mode {
|
||||
if let Some(PhraseListMode::Length(phrase, new_length, focus)) = mode {
|
||||
if *focused && i == *phrase {
|
||||
length.pulses = *new_length;
|
||||
length.focus = Some(*focus);
|
||||
|
|
@ -136,7 +120,7 @@ render!(|self: PhraseListView<'a>|{
|
|||
})),
|
||||
Tui::bold(true, {
|
||||
let mut row2 = format!(" {name}");
|
||||
if let Some(PhrasesMode::Rename(phrase, _)) = mode {
|
||||
if let Some(PhraseListMode::Rename(phrase, _)) = mode {
|
||||
if *focused && i == *phrase {
|
||||
row2 = format!("{row2}▄");
|
||||
}
|
||||
|
|
@ -175,7 +159,7 @@ impl Command<PhraseListModel> for PhrasesCommand {
|
|||
PhraseRenameCommand::Begin => {
|
||||
let length = state.phrases()[state.phrase_index()].read().unwrap().length;
|
||||
*state.phrases_mode_mut() = Some(
|
||||
PhrasesMode::Length(state.phrase_index(), length, PhraseLengthFocus::Bar)
|
||||
PhraseListMode::Length(state.phrase_index(), length, PhraseLengthFocus::Bar)
|
||||
);
|
||||
None
|
||||
},
|
||||
|
|
@ -185,7 +169,7 @@ impl Command<PhraseListModel> for PhrasesCommand {
|
|||
PhraseLengthCommand::Begin => {
|
||||
let name = state.phrases()[state.phrase_index()].read().unwrap().name.clone();
|
||||
*state.phrases_mode_mut() = Some(
|
||||
PhrasesMode::Rename(state.phrase_index(), name)
|
||||
PhraseListMode::Rename(state.phrase_index(), name)
|
||||
);
|
||||
None
|
||||
},
|
||||
|
|
@ -194,7 +178,7 @@ impl Command<PhraseListModel> for PhrasesCommand {
|
|||
Import(command) => match command {
|
||||
FileBrowserCommand::Begin => {
|
||||
*state.phrases_mode_mut() = Some(
|
||||
PhrasesMode::Import(state.phrase_index(), FileBrowser::new(None)?)
|
||||
PhraseListMode::Import(state.phrase_index(), FileBrowser::new(None)?)
|
||||
);
|
||||
None
|
||||
},
|
||||
|
|
@ -203,7 +187,7 @@ impl Command<PhraseListModel> for PhrasesCommand {
|
|||
Export(command) => match command {
|
||||
FileBrowserCommand::Begin => {
|
||||
*state.phrases_mode_mut() = Some(
|
||||
PhrasesMode::Export(state.phrase_index(), FileBrowser::new(None)?)
|
||||
PhraseListMode::Export(state.phrase_index(), FileBrowser::new(None)?)
|
||||
);
|
||||
None
|
||||
},
|
||||
|
|
@ -229,10 +213,10 @@ impl HasPhrases for PhraseListModel {
|
|||
impl InputToCommand<Tui, PhraseListModel> for PhrasesCommand {
|
||||
fn input_to_command (state: &PhraseListModel, input: &TuiInput) -> Option<Self> {
|
||||
Some(match state.phrases_mode() {
|
||||
Some(PhrasesMode::Rename(..)) => Self::Rename(Rename::input_to_command(state, input)?),
|
||||
Some(PhrasesMode::Length(..)) => Self::Length(Length::input_to_command(state, input)?),
|
||||
Some(PhrasesMode::Import(..)) => Self::Import(Browse::input_to_command(state, input)?),
|
||||
Some(PhrasesMode::Export(..)) => Self::Export(Browse::input_to_command(state, input)?),
|
||||
Some(PhraseListMode::Rename(..)) => Self::Rename(Rename::input_to_command(state, input)?),
|
||||
Some(PhraseListMode::Length(..)) => Self::Length(Length::input_to_command(state, input)?),
|
||||
Some(PhraseListMode::Import(..)) => Self::Import(Browse::input_to_command(state, input)?),
|
||||
Some(PhraseListMode::Export(..)) => Self::Export(Browse::input_to_command(state, input)?),
|
||||
_ => to_phrases_command(state, input)?
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ impl Command<PhraseListModel> for PhraseRenameCommand {
|
|||
fn execute (self, state: &mut PhraseListModel) -> Perhaps<Self> {
|
||||
use PhraseRenameCommand::*;
|
||||
match state.phrases_mode_mut().clone() {
|
||||
Some(PhrasesMode::Rename(phrase, ref mut old_name)) => match self {
|
||||
Some(PhraseListMode::Rename(phrase, ref mut old_name)) => match self {
|
||||
Set(s) => {
|
||||
state.phrases()[phrase].write().unwrap().name = s.into();
|
||||
return Ok(Some(Self::Set(old_name.clone())))
|
||||
|
|
@ -36,7 +36,7 @@ impl Command<PhraseListModel> for PhraseRenameCommand {
|
|||
impl InputToCommand<Tui, PhraseListModel> for PhraseRenameCommand {
|
||||
fn input_to_command (state: &PhraseListModel, from: &TuiInput) -> Option<Self> {
|
||||
use KeyCode::{Char, Backspace, Enter, Esc};
|
||||
if let Some(PhrasesMode::Rename(_, ref old_name)) = state.phrases_mode() {
|
||||
if let Some(PhraseListMode::Rename(_, ref old_name)) = state.phrases_mode() {
|
||||
Some(match from.event() {
|
||||
key!(Char(c)) => {
|
||||
let mut new_name = old_name.clone();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue