#[derive(Clone, Debug, PartialEq)]
pub struct FocusManager<Id> {
order: Vec<Id>,
focused: Option<usize>,
}
impl<Id> Default for FocusManager<Id> {
fn default() -> Self {
Self {
order: Vec::new(),
focused: None,
}
}
}
impl<Id: Clone + PartialEq> FocusManager<Id> {
pub fn new(order: Vec<Id>) -> Self {
Self {
order,
focused: None,
}
}
pub fn with_initial_focus(order: Vec<Id>) -> Self {
let focused = if order.is_empty() { None } else { Some(0) };
Self { order, focused }
}
pub fn focused(&self) -> Option<&Id> {
self.focused.and_then(|idx| self.order.get(idx))
}
pub fn is_focused(&self, id: &Id) -> bool {
self.focused() == Some(id)
}
pub fn focus(&mut self, id: &Id) -> bool {
if let Some(idx) = self.order.iter().position(|item| item == id) {
self.focused = Some(idx);
true
} else {
false
}
}
pub fn focus_next(&mut self) -> Option<&Id> {
if self.order.is_empty() {
return None;
}
let next_idx = match self.focused {
Some(idx) => (idx + 1) % self.order.len(),
None => 0,
};
self.focused = Some(next_idx);
self.order.get(next_idx)
}
pub fn focus_prev(&mut self) -> Option<&Id> {
if self.order.is_empty() {
return None;
}
let prev_idx = match self.focused {
Some(idx) => {
if idx == 0 {
self.order.len() - 1
} else {
idx - 1
}
}
None => self.order.len() - 1,
};
self.focused = Some(prev_idx);
self.order.get(prev_idx)
}
pub fn blur(&mut self) {
self.focused = None;
}
pub fn focus_first(&mut self) -> Option<&Id> {
if self.order.is_empty() {
self.focused = None;
None
} else {
self.focused = Some(0);
self.order.first()
}
}
pub fn focus_last(&mut self) -> Option<&Id> {
if self.order.is_empty() {
self.focused = None;
None
} else {
self.focused = Some(self.order.len() - 1);
self.order.last()
}
}
pub fn order(&self) -> &[Id] {
&self.order
}
pub fn is_empty(&self) -> bool {
self.order.is_empty()
}
pub fn len(&self) -> usize {
self.order.len()
}
}
#[cfg(test)]
mod tests;