use crate::{components as cpn, error::{FtuiResult, FtuiError}, trigger::Trigger};
pub struct Selector {
up_trig: Option<Trigger>,
down_trig: Option<Trigger>,
selc_trig: Option<Trigger>,
on: usize,
}
impl Selector {
pub fn new(up_trig: Trigger, down_trig: Trigger, selc_trig: Trigger) -> Self {
Selector {
up_trig: Some(up_trig),
down_trig: Some(down_trig),
selc_trig: Some(selc_trig),
on: 0,
}
}
pub fn no_triggers() -> Self {
Selector {
up_trig: None,
down_trig: None,
selc_trig: None,
on: 0,
}
}
pub(crate) fn up(&mut self, options: &mut Vec<cpn::Option>) -> bool {
if self.on == 0 {
return false;
}
options[self.on].set_selc_on(false);
self.on -= 1;
options[self.on].set_selc_on(true);
true
}
pub(crate) fn down(&mut self, options: &mut Vec<cpn::Option>) -> bool {
if self.on == options.len() - 1 {
return false;
}
options[self.on].set_selc_on(false);
self.on += 1;
options[self.on].set_selc_on(true);
true
}
pub(crate) fn select(&mut self, options: &mut Vec<cpn::Option>) -> FtuiResult<bool> {
if let Some(callback) = options[self.on].callback() {
callback.call()?;
}
options[self.on].set_is_selc(true);
Ok(true)
}
#[inline]
fn have_trigs(&self) -> bool {
matches!(
(&self.up_trig, &self.down_trig, &self.selc_trig),
(Some(_), Some(_), Some(_)))
}
pub(crate) fn looper(&mut self, options: &mut Vec<cpn::Option>) -> FtuiResult<bool> {
if !self.have_trigs() {
return Err(FtuiError::SelectorNoTriggers);
}
if self.up_trig.as_ref().unwrap().check()? && self.up(options) {
Ok(true)
} else if self.down_trig.as_ref().unwrap().check()? && self.down(options) {
Ok(true)
} else if self.selc_trig.as_ref().unwrap().check()? {
self.select(options)?;
Ok(true)
} else {
Ok(false)
}
}
#[inline]
pub fn up_trig_mut(&mut self) -> FtuiResult<&mut Trigger> {
self.up_trig.as_mut().ok_or(FtuiError::SelectorNoTriggers)
}
#[inline]
pub fn down_trig_mut(&mut self) -> FtuiResult<&mut Trigger> {
self.down_trig.as_mut().ok_or(FtuiError::SelectorNoTriggers)
}
#[inline]
pub fn select_trig_mut(&mut self) -> FtuiResult<&mut Trigger> {
self.selc_trig.as_mut().ok_or(FtuiError::SelectorNoTriggers)
}
pub fn update_trig_arg<T, U, V>(
&mut self, up_arg: T, down_arg: U, selc_arg: V
) -> FtuiResult<()>
where
T: 'static,
U: 'static,
V: 'static,
{
match (&mut self.up_trig, &mut self.down_trig, &mut self.selc_trig) {
(Some(u), Some(d), Some(s)) => {
u.update_arg(up_arg);
d.update_arg(down_arg);
s.update_arg(selc_arg);
Ok(())
}
_ => Err(FtuiError::SelectorNoTriggers),
}
}
}