Newer
Older
use embedded_graphics::{pixelcolor::Rgb565, prelude::DrawTarget};
gui::{
chat::Chat, chat_list::ChatList, contact_view::ContactView, selector::Selector,
status::StatusBar, Element,
},
storage::{ContactIter, Storage, MAX_CONTACTS, MAX_CONTACT_NAME_LENGTH},
pub enum View {
MainMenu(Selector<&'static str, [&'static str; 3]>),
Contacts(
Selector<
String<MAX_CONTACT_NAME_LENGTH>,
Vec<String<MAX_CONTACT_NAME_LENGTH>, MAX_CONTACTS>,
>,
),
ContactOptions(Selector<&'static str, [&'static str; 3]>, usize),
let menu = Selector::new(["Contacts", "Messages", "Settings"], id);
Self::MainMenu(menu)
}
pub fn new_contacts(id: usize, contacts: &ContactIter) -> Self {
let mut contact_names: Vec<_, MAX_CONTACTS> = contacts.map(|c| c.name.clone()).collect();
// If we run out of space, we automatically hide the "Add" button
let _ = contact_names.push(String::try_from("Add New").unwrap());
Self::Contacts(Selector::new(contact_names, id))
}
pub fn new_contact_options(contact_id: usize, selected_id: usize) -> Self {
let opts = Selector::new(["View", "Edit", "Message"], selected_id);
pub fn from_main_menu_id(id: usize, contacts: &ContactIter, storage: &Storage) -> Option<Self> {
_ => None,
}
}
pub fn to_main_menu_id(&self) -> usize {
match self {
View::Contacts(_) => 0,
_ => unreachable!(),
}
}
pub fn from_contact_options_id(
id: usize,
contact_id: usize,
Some(View::ContactView(
ContactView::new(contact, false),
contact_id,
Some(View::ContactView(
ContactView::new(contact, true),
contact_id,
2 => {
let contact = contacts
.nth(contact_id)
.unwrap_or_else(|| storage.new_contact());
Some(View::Chat(Chat::new(contact.callsign, contact.ssid), 0))
}
fn render<E, DT: DrawTarget<Color = Rgb565, Error = E>>(
&mut self,
dt: &mut DT,
) -> Result<(), E> {
match self {
View::MainMenu(m) => m.render(dt),
View::Contacts(c) => c.render(dt),
View::ContactView(c, _, _) => c.render(dt),
View::ChatList(c) => c.render(dt, storage),
View::Chat(c, _) => c.render(dt, storage),
match self {
View::MainMenu(m) => m.key_push(k),
View::Contacts(c) => c.key_push(k),
}
}
fn touchpad_scroll(&mut self, x: i8, y: i8) {
match self {
View::MainMenu(m) => m.touchpad_scroll(x, y),
View::Contacts(c) => c.touchpad_scroll(x, y),
View::ContactView(c, _, _) => c.touchpad_scroll(x, y),
impl Default for View {
fn default() -> Self {
Self::new_main_menu(0)
}
}
}
impl Controller {
pub fn new(volt_meter: VoltMeter) -> Self {
Self {
status: StatusBar::new(volt_meter),
}
}
}
impl Element for Controller {
fn render<E, DT: DrawTarget<Color = Rgb565, Error = E>>(
&mut self,
dt: &mut DT,
) -> Result<(), E> {
dt.clear(Rgb565::new(0, 32, 16))?;
self.status.render(dt)?;
Ok(())
}
fn key_push(&mut self, k: KeyCode) {
View::from_main_menu_id(m.selected(), &self.storage.contacts(), &self.storage)
// Go direct to edit page
self.cur_view =
self.cur_view = View::new_contact_options(c.selected(), 0);
(View::ContactOptions(c, contact_id), KeyCode::Touchpad) => {
if let Some(new_view) =
View::from_contact_options_id(c.selected(), *contact_id, &self.storage)
{
let (callsign, ssid) = self
.storage
.message_addressees()
.nth(cl.selected())
.unwrap();
self.cur_view = View::Chat(Chat::new(callsign, ssid), cl.selected());
self.cur_view = View::new_contacts(*id, &self.storage.contacts());
(View::ContactView(cv, contact_id, selected_id), KeyCode::Back) => {
// TODO only need to call this if we actually edited
self.cur_view = View::new_contact_options(*contact_id, *selected_id);
self.cur_view = View::ChatList(ChatList::new(&self.storage, *selected_id));
(_, KeyCode::Back) => {
let id = self.cur_view.to_main_menu_id();
(View::ContactView(cv, contact_id, _), k) => {
self.cur_view = View::new_contacts(*contact_id, &self.storage.contacts());
}
}
fn touchpad_scroll(&mut self, x: i8, y: i8) {