mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 11:46:41 +01:00
wip: refactor pt.11, 154 errors
This commit is contained in:
parent
355b34c738
commit
47c9cd2fe8
3 changed files with 107 additions and 54 deletions
|
|
@ -8,14 +8,52 @@ pub struct PhrasePool {
|
||||||
|
|
||||||
#[derive(Clone, PartialEq)]
|
#[derive(Clone, PartialEq)]
|
||||||
pub enum PhrasePoolCommand {
|
pub enum PhrasePoolCommand {
|
||||||
Select(usize),
|
|
||||||
Add(usize),
|
Add(usize),
|
||||||
Delete(usize),
|
Delete(usize),
|
||||||
Duplicate(usize),
|
Duplicate(usize),
|
||||||
Swap(usize),
|
Swap(usize, usize),
|
||||||
RandomColor(usize),
|
RandomColor(usize),
|
||||||
Import(String),
|
Import(usize, String),
|
||||||
Export(String),
|
Export(usize, String),
|
||||||
SetName(String),
|
SetName(usize, String),
|
||||||
SetLength(String),
|
SetLength(usize, usize),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Command<PhrasePool> for PhrasePoolCommand {
|
||||||
|
fn execute (self, state: &mut PhrasePool) -> Perhaps<Self> {
|
||||||
|
match self {
|
||||||
|
Self::Add(index) => {
|
||||||
|
//Self::Append => { view.append_new(None, None) },
|
||||||
|
//Self::Insert => { view.insert_new(None, None) },
|
||||||
|
},
|
||||||
|
Self::Delete(index) => {
|
||||||
|
//if view.phrase > 0 {
|
||||||
|
//view.state.phrases.remove(view.phrase);
|
||||||
|
//view.phrase = view.phrase.min(view.state.phrases.len().saturating_sub(1));
|
||||||
|
//}
|
||||||
|
},
|
||||||
|
Self::Duplicate(index) => {
|
||||||
|
//let mut phrase = view.phrase().read().unwrap().duplicate();
|
||||||
|
//phrase.color = ItemColorTriplet::random_near(phrase.color, 0.25);
|
||||||
|
//view.phrases.insert(view.phrase + 1, Arc::new(RwLock::new(phrase)));
|
||||||
|
//view.phrase += 1;
|
||||||
|
},
|
||||||
|
Self::Swap(index, other) => {
|
||||||
|
//Self::MoveUp => { view.move_up() },
|
||||||
|
//Self::MoveDown => { view.move_down() },
|
||||||
|
},
|
||||||
|
Self::RandomColor(index) => {
|
||||||
|
//view.phrase().write().unwrap().color = ItemColorTriplet::random();
|
||||||
|
},
|
||||||
|
Self::Import(index, path) => {
|
||||||
|
},
|
||||||
|
Self::Export(index, path) => {
|
||||||
|
},
|
||||||
|
Self::SetName(index, name) => {
|
||||||
|
},
|
||||||
|
Self::SetLength(index, length) => {
|
||||||
|
},
|
||||||
|
}
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ use crate::*;
|
||||||
|
|
||||||
pub struct PhrasePoolView<E: Engine> {
|
pub struct PhrasePoolView<E: Engine> {
|
||||||
_engine: PhantomData<E>,
|
_engine: PhantomData<E>,
|
||||||
state: PhrasePool,
|
pub state: PhrasePool,
|
||||||
/// Selected phrase
|
/// Selected phrase
|
||||||
pub phrase: usize,
|
pub phrase: usize,
|
||||||
/// Scroll offset
|
/// Scroll offset
|
||||||
|
|
@ -23,8 +23,8 @@ pub enum PhrasePoolMode {
|
||||||
Length(usize, usize, PhraseLengthFocus),
|
Length(usize, usize, PhraseLengthFocus),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E: Engine> PhrasePool<E> {
|
impl<E: Engine> PhrasePoolView<E> {
|
||||||
pub fn new (phrases: PhrasePool) -> Self {
|
pub fn new (state: PhrasePool) -> Self {
|
||||||
Self {
|
Self {
|
||||||
_engine: Default::default(),
|
_engine: Default::default(),
|
||||||
scroll: 0,
|
scroll: 0,
|
||||||
|
|
@ -32,13 +32,15 @@ impl<E: Engine> PhrasePool<E> {
|
||||||
mode: None,
|
mode: None,
|
||||||
focused: false,
|
focused: false,
|
||||||
entered: false,
|
entered: false,
|
||||||
phrases,
|
state,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn len (&self) -> usize { self.phrases.len() }
|
pub fn len (&self) -> usize {
|
||||||
pub fn phrase (&self) -> &Arc<RwLock<Phrase>> { &self.phrases[self.phrase] }
|
self.state.phrases.len()
|
||||||
pub fn select_prev (&mut self) { self.phrase = self.index_before(self.phrase) }
|
}
|
||||||
pub fn select_next (&mut self) { self.phrase = self.index_after(self.phrase) }
|
pub fn phrase (&self) -> &Arc<RwLock<Phrase>> {
|
||||||
|
&self.state.phrases[self.phrase]
|
||||||
|
}
|
||||||
pub fn index_before (&self, index: usize) -> usize {
|
pub fn index_before (&self, index: usize) -> usize {
|
||||||
index.overflowing_sub(1).0.min(self.len() - 1)
|
index.overflowing_sub(1).0.min(self.len() - 1)
|
||||||
}
|
}
|
||||||
|
|
@ -46,8 +48,8 @@ impl<E: Engine> PhrasePool<E> {
|
||||||
(index + 1) % self.len()
|
(index + 1) % self.len()
|
||||||
}
|
}
|
||||||
pub fn index_of (&self, phrase: &Phrase) -> Option<usize> {
|
pub fn index_of (&self, phrase: &Phrase) -> Option<usize> {
|
||||||
for i in 0..self.phrases.len() {
|
for i in 0..self.state.phrases.len() {
|
||||||
if *self.phrases[i].read().unwrap() == *phrase { return Some(i) }
|
if *self.state.phrases[i].read().unwrap() == *phrase { return Some(i) }
|
||||||
}
|
}
|
||||||
return None
|
return None
|
||||||
}
|
}
|
||||||
|
|
@ -58,62 +60,58 @@ impl<E: Engine> PhrasePool<E> {
|
||||||
}
|
}
|
||||||
pub fn delete_selected (&mut self) {
|
pub fn delete_selected (&mut self) {
|
||||||
if self.phrase > 0 {
|
if self.phrase > 0 {
|
||||||
self.phrases.remove(self.phrase);
|
self.state.phrases.remove(self.phrase);
|
||||||
self.phrase = self.phrase.min(self.phrases.len().saturating_sub(1));
|
self.phrase = self.phrase.min(self.state.phrases.len().saturating_sub(1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn append_new (&mut self, name: Option<&str>, color: Option<ItemColorTriplet>) {
|
pub fn append_new (&mut self, name: Option<&str>, color: Option<ItemColorTriplet>) {
|
||||||
self.phrases.push(Self::new_phrase(name, color));
|
self.state.phrases.push(Self::new_phrase(name, color));
|
||||||
self.phrase = self.phrases.len() - 1;
|
self.phrase = self.state.phrases.len() - 1;
|
||||||
}
|
}
|
||||||
pub fn insert_new (&mut self, name: Option<&str>, color: Option<ItemColorTriplet>) {
|
pub fn insert_new (&mut self, name: Option<&str>, color: Option<ItemColorTriplet>) {
|
||||||
self.phrases.insert(self.phrase + 1, Self::new_phrase(name, color));
|
self.state.phrases.insert(self.phrase + 1, Self::new_phrase(name, color));
|
||||||
self.phrase += 1;
|
self.phrase += 1;
|
||||||
}
|
}
|
||||||
pub fn insert_dup (&mut self) {
|
pub fn insert_dup (&mut self) {
|
||||||
let mut phrase = self.phrases[self.phrase].read().unwrap().duplicate();
|
let mut phrase = self.state.phrases[self.phrase].read().unwrap().duplicate();
|
||||||
phrase.color = ItemColorTriplet::random_near(phrase.color, 0.25);
|
phrase.color = ItemColorTriplet::random_near(phrase.color, 0.25);
|
||||||
self.phrases.insert(self.phrase + 1, Arc::new(RwLock::new(phrase)));
|
self.state.phrases.insert(self.phrase + 1, Arc::new(RwLock::new(phrase)));
|
||||||
self.phrase += 1;
|
self.phrase += 1;
|
||||||
}
|
}
|
||||||
pub fn randomize_color (&mut self) {
|
|
||||||
let mut phrase = self.phrases[self.phrase].write().unwrap();
|
|
||||||
phrase.color = ItemColorTriplet::random();
|
|
||||||
}
|
|
||||||
pub fn begin_rename (&mut self) {
|
pub fn begin_rename (&mut self) {
|
||||||
self.mode = Some(PhrasePoolMode::Rename(
|
self.mode = Some(PhrasePoolMode::Rename(
|
||||||
self.phrase,
|
self.phrase,
|
||||||
self.phrases[self.phrase].read().unwrap().name.clone()
|
self.state.phrases[self.phrase].read().unwrap().name.clone()
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
pub fn begin_length (&mut self) {
|
pub fn begin_length (&mut self) {
|
||||||
self.mode = Some(PhrasePoolMode::Length(
|
self.mode = Some(PhrasePoolMode::Length(
|
||||||
self.phrase,
|
self.phrase,
|
||||||
self.phrases[self.phrase].read().unwrap().length,
|
self.state.phrases[self.phrase].read().unwrap().length,
|
||||||
PhraseLengthFocus::Bar
|
PhraseLengthFocus::Bar
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
pub fn move_up (&mut self) {
|
pub fn move_up (&mut self) {
|
||||||
if self.phrase > 1 {
|
if self.phrase > 1 {
|
||||||
self.phrases.swap(self.phrase - 1, self.phrase);
|
self.state.phrases.swap(self.phrase - 1, self.phrase);
|
||||||
self.phrase -= 1;
|
self.phrase -= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn move_down (&mut self) {
|
pub fn move_down (&mut self) {
|
||||||
if self.phrase < self.phrases.len().saturating_sub(1) {
|
if self.phrase < self.state.phrases.len().saturating_sub(1) {
|
||||||
self.phrases.swap(self.phrase + 1, self.phrase);
|
self.state.phrases.swap(self.phrase + 1, self.phrase);
|
||||||
self.phrase += 1;
|
self.phrase += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Display phrases always in order of appearance
|
// TODO: Display phrases always in order of appearance
|
||||||
impl Content for PhrasePool<Tui> {
|
impl Content for PhrasePoolView<Tui> {
|
||||||
type Engine = Tui;
|
type Engine = Tui;
|
||||||
fn content (&self) -> impl Widget<Engine = Tui> {
|
fn content (&self) -> impl Widget<Engine = Tui> {
|
||||||
let Self { focused, phrases, mode, .. } = self;
|
let Self { focused, state, mode, .. } = self;
|
||||||
let content = col!(
|
let content = col!(
|
||||||
(i, phrase) in phrases.iter().enumerate() => Layers::new(|add|{
|
(i, phrase) in state.iter().enumerate() => Layers::new(|add|{
|
||||||
let Phrase { ref name, color, length, .. } = *phrase.read().unwrap();
|
let Phrase { ref name, color, length, .. } = *phrase.read().unwrap();
|
||||||
let mut length = PhraseLength::new(length, None);
|
let mut length = PhraseLength::new(length, None);
|
||||||
if let Some(PhrasePoolMode::Length(phrase, new_length, focus)) = mode {
|
if let Some(PhrasePoolMode::Length(phrase, new_length, focus)) = mode {
|
||||||
|
|
@ -138,7 +136,7 @@ impl Content for PhrasePool<Tui> {
|
||||||
let content = content.fill_xy().bg(Color::Rgb(28, 35, 25)).border(border);
|
let content = content.fill_xy().bg(Color::Rgb(28, 35, 25)).border(border);
|
||||||
let title_color = if *focused {Color::Rgb(150, 160, 90)} else {Color::Rgb(120, 130, 100)};
|
let title_color = if *focused {Color::Rgb(150, 160, 90)} else {Color::Rgb(120, 130, 100)};
|
||||||
let upper_left = format!("[{}] Phrases", if self.entered {"■"} else {" "});
|
let upper_left = format!("[{}] Phrases", if self.entered {"■"} else {" "});
|
||||||
let upper_right = format!("({})", phrases.len());
|
let upper_right = format!("({})", state.len());
|
||||||
lay!(
|
lay!(
|
||||||
content,
|
content,
|
||||||
TuiStyle::fg(upper_left.to_string(), title_color).push_x(1).align_nw().fill_xy(),
|
TuiStyle::fg(upper_left.to_string(), title_color).push_x(1).align_nw().fill_xy(),
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ use crate::*;
|
||||||
|
|
||||||
#[derive(Clone, PartialEq)]
|
#[derive(Clone, PartialEq)]
|
||||||
pub enum PhrasePoolViewCommand {
|
pub enum PhrasePoolViewCommand {
|
||||||
|
Select(usize),
|
||||||
Edit(PhrasePoolCommand),
|
Edit(PhrasePoolCommand),
|
||||||
Rename(PhraseRenameCommand),
|
Rename(PhraseRenameCommand),
|
||||||
Length(PhraseLengthCommand),
|
Length(PhraseLengthCommand),
|
||||||
|
|
@ -20,10 +21,10 @@ impl InputToCommand<Tui, PhrasePoolView<Tui>> for PhrasePoolViewCommand {
|
||||||
use PhraseRenameCommand as Rename;
|
use PhraseRenameCommand as Rename;
|
||||||
use PhraseLengthCommand as Length;
|
use PhraseLengthCommand as Length;
|
||||||
match input.event() {
|
match input.event() {
|
||||||
key!(KeyCode::Up) => Some(Cmd::Edit(Edit::Select(0))),
|
key!(KeyCode::Up) => Some(Cmd::Select(0)),
|
||||||
key!(KeyCode::Down) => Some(Cmd::Edit(Edit::Select(0))),
|
key!(KeyCode::Down) => Some(Cmd::Select(0)),
|
||||||
key!(KeyCode::Char(',')) => Some(Cmd::Edit(Edit::Swap(0))),
|
key!(KeyCode::Char(',')) => Some(Cmd::Edit(Edit::Swap(0, 0))),
|
||||||
key!(KeyCode::Char('.')) => Some(Cmd::Edit(Edit::Swap(0))),
|
key!(KeyCode::Char('.')) => Some(Cmd::Edit(Edit::Swap(0, 0))),
|
||||||
key!(KeyCode::Delete) => Some(Cmd::Edit(Edit::Delete(0))),
|
key!(KeyCode::Delete) => Some(Cmd::Edit(Edit::Delete(0))),
|
||||||
key!(KeyCode::Char('a')) => Some(Cmd::Edit(Edit::Add(0))),
|
key!(KeyCode::Char('a')) => Some(Cmd::Edit(Edit::Add(0))),
|
||||||
key!(KeyCode::Char('i')) => Some(Cmd::Edit(Edit::Add(0))),
|
key!(KeyCode::Char('i')) => Some(Cmd::Edit(Edit::Add(0))),
|
||||||
|
|
@ -45,23 +46,39 @@ impl InputToCommand<Tui, PhrasePoolView<Tui>> for PhrasePoolViewCommand {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E: Engine> Command<PhrasePoolView<E>> for PhrasePoolViewCommand {
|
impl<E: Engine> Command<PhrasePoolView<E>> for PhrasePoolViewCommand {
|
||||||
fn execute (self, state: &mut PhrasePoolView<E>) -> Perhaps<Self> {
|
fn execute (self, view: &mut PhrasePoolView<E>) -> Perhaps<Self> {
|
||||||
use PhrasePoolViewCommand::*;
|
|
||||||
use PhraseRenameCommand as Rename;
|
use PhraseRenameCommand as Rename;
|
||||||
use PhraseLengthCommand as Length;
|
use PhraseLengthCommand as Length;
|
||||||
match self {
|
match self {
|
||||||
Rename(Rename::Begin) => { state.begin_rename() },
|
Self::Select(phrase) => {
|
||||||
Length(Length::Begin) => { state.begin_length() },
|
view.phrase = phrase
|
||||||
Prev => { state.select_prev() },
|
},
|
||||||
Next => { state.select_next() },
|
Self::Edit(command) => {
|
||||||
Delete => { state.delete_selected() },
|
return Ok(command.execute(&mut view.state)?.map(Self::Edit))
|
||||||
Append => { state.append_new(None, None) },
|
}
|
||||||
Insert => { state.insert_new(None, None) },
|
Self::Rename(command) => match command {
|
||||||
Duplicate => { state.insert_dup() },
|
Rename::Begin => {
|
||||||
RandomColor => { state.randomize_color() },
|
view.mode = Some(PhrasePoolMode::Rename(
|
||||||
MoveUp => { state.move_up() },
|
view.phrase,
|
||||||
MoveDown => { state.move_down() },
|
view.state.phrases[view.phrase].read().unwrap().name.clone()
|
||||||
_ => unreachable!(),
|
))
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
return Ok(command.execute(view)?.map(Self::Rename))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Self::Length(command) => match command {
|
||||||
|
Length::Begin => {
|
||||||
|
view.mode = Some(PhrasePoolMode::Length(
|
||||||
|
view.phrase,
|
||||||
|
view.state.phrases[view.phrase].read().unwrap().length,
|
||||||
|
PhraseLengthFocus::Bar
|
||||||
|
))
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
return Ok(command.execute(view)?.map(Self::Length))
|
||||||
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue