1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
pub trait Selectable {
/// True iff the content is empty
fn is_empty(&self) -> bool;
/// Number of element in content
fn len(&self) -> usize;
/// Select next element in content
fn next(&mut self);
/// Select previous element in content
fn prev(&mut self);
/// Current index of selected element.
/// 0 if the content is empty (I know, could be an option)
fn index(&self) -> usize;
/// set the index to the value if possible
fn set_index(&mut self, index: usize);
}
pub trait Content<T>: Selectable {
/// Returns the selected element if content isn't empty
fn selected(&self) -> Option<&T>;
/// Reference to the content as a vector.
fn content(&self) -> &Vec<T>;
/// add an element to the content
fn push(&mut self, t: T);
/// [`tuikit::attr:Attr`] used to display an element
fn attr(&self, index: usize, attr: &tuikit::attr::Attr) -> tuikit::attr::Attr;
}
/// Implement the `SelectableContent` for struct `$struc` with content type `$content_type`.
/// This trait allows to navigate through a vector of element `content_type`.
/// It implements: `is_empty`, `len`, `next`, `prev`, `selected`.
/// `selected` returns an optional reference to the value.
#[macro_export]
macro_rules! impl_selectable {
($struct:ident) => {
use $crate::modes::Selectable;
/// Implement a selectable content for this struct.
/// This trait allows to navigate through a vector of element `content_type`.
/// It implements: `is_empty`, `len`, `next`, `prev`, `selected`.
/// `selected` returns an optional reference to the value.
impl Selectable for $struct {
/// True if the content is empty.
fn is_empty(&self) -> bool {
self.content.is_empty()
}
/// The size of the content.
fn len(&self) -> usize {
self.content.len()
}
/// Select the prev item.
fn prev(&mut self) {
if self.is_empty() {
self.index = 0
} else if self.index > 0 {
self.index -= 1;
} else {
self.index = self.len() - 1
}
}
/// Select the next item.
fn next(&mut self) {
if self.is_empty() {
self.index = 0;
} else {
self.index = (self.index + 1) % self.len()
}
}
/// Returns the index of the selected item.
fn index(&self) -> usize {
self.index
}
/// Set the index to a new value if the value is below the length.
fn set_index(&mut self, index: usize) {
if index < self.len() {
self.index = index;
}
}
}
};
}
/// Implement the `SelectableContent` for struct `$struc` with content type `$content_type`.
/// This trait allows to navigate through a vector of element `content_type`.
/// It implements: `is_empty`, `len`, `next`, `prev`, `selected`.
/// `selected` returns an optional reference to the value.
#[macro_export]
macro_rules! impl_content {
($content_type:ident, $struct:ident) => {
use $crate::modes::Content;
/// Implement a selectable content for this struct.
/// This trait allows to navigate through a vector of element `content_type`.
/// It implements: `is_empty`, `len`, `next`, `prev`, `selected`.
/// `selected` returns an optional reference to the value.
impl Content<$content_type> for $struct {
/// Returns a reference to the selected content.
fn selected(&self) -> Option<&$content_type> {
match self.is_empty() {
true => None,
false => Some(&self.content[self.index]),
}
}
/// A reference to the content.
fn content(&self) -> &Vec<$content_type> {
&self.content
}
/// Reverse the received effect if the index match the selected index.
fn attr(&self, index: usize, attr: &tuikit::attr::Attr) -> tuikit::attr::Attr {
let mut attr = *attr;
if index == self.index() {
attr.effect |= tuikit::attr::Effect::REVERSE;
}
attr
}
fn push(&mut self, element: $content_type) {
self.content.push(element)
}
}
};
}