use std::any::Any;
use rusty_bubbles::list;
use rusty_bubbletea::model::Model as ModelTrait;
use rusty_bubbletea::screen::WindowSizeMsg;
use rusty_bubbletea::{quit, Cmd, KeyPressMsg, Msg, Program, View};
use rusty_lipgloss::new_style;
fn doc_style() -> rusty_lipgloss::Style {
new_style().margin(&[1, 2])
}
#[derive(Debug, Clone)]
struct Item {
title: String,
desc: String,
}
impl list::Item for Item {
fn filter_value(&self) -> String {
self.title.clone()
}
fn box_clone(&self) -> Box<dyn list::Item + Send + Sync> {
Box::new(self.clone())
}
fn as_any(&self) -> &dyn Any {
self
}
fn as_default_item(&self) -> Option<&dyn list::DefaultItem> {
Some(self)
}
}
impl list::DefaultItem for Item {
fn title(&self) -> String {
self.title.clone()
}
fn description(&self) -> String {
self.desc.clone()
}
}
struct Model {
list: list::Model,
}
impl Model {
fn new() -> Self {
let items: Vec<Box<dyn list::Item + Send + Sync>> = vec![
Box::new(Item {
title: "Raspberry Pi’s".to_string(),
desc: "I have ’em all over my house".to_string(),
}),
Box::new(Item {
title: "Nutella".to_string(),
desc: "It's good on toast".to_string(),
}),
Box::new(Item {
title: "Bitter melon".to_string(),
desc: "It cools you down".to_string(),
}),
Box::new(Item {
title: "Nice socks".to_string(),
desc: "And by that I mean socks without holes".to_string(),
}),
Box::new(Item {
title: "Eight hours of sleep".to_string(),
desc: "I had this once".to_string(),
}),
Box::new(Item {
title: "Cats".to_string(),
desc: "Usually".to_string(),
}),
Box::new(Item {
title: "Plantasia, the album".to_string(),
desc: "My plants love it too".to_string(),
}),
Box::new(Item {
title: "Pour over coffee".to_string(),
desc: "It takes forever to make though".to_string(),
}),
Box::new(Item {
title: "VR".to_string(),
desc: "Virtual reality...what is there to say?".to_string(),
}),
Box::new(Item {
title: "Noguchi Lamps".to_string(),
desc: "Such pleasing organic forms".to_string(),
}),
Box::new(Item {
title: "Linux".to_string(),
desc: "Pretty much the best OS".to_string(),
}),
Box::new(Item {
title: "Business school".to_string(),
desc: "Just kidding".to_string(),
}),
Box::new(Item {
title: "Pottery".to_string(),
desc: "Wet clay is a great feeling".to_string(),
}),
Box::new(Item {
title: "Shampoo".to_string(),
desc: "Nothing like clean hair".to_string(),
}),
Box::new(Item {
title: "Table tennis".to_string(),
desc: "It’s surprisingly exhausting".to_string(),
}),
Box::new(Item {
title: "Milk crates".to_string(),
desc: "Great for packing in your extra stuff".to_string(),
}),
Box::new(Item {
title: "Afternoon tea".to_string(),
desc: "Especially the tea sandwich part".to_string(),
}),
Box::new(Item {
title: "Stickers".to_string(),
desc: "The thicker the vinyl the better".to_string(),
}),
Box::new(Item {
title: "20° Weather".to_string(),
desc: "Celsius, not Fahrenheit".to_string(),
}),
Box::new(Item {
title: "Warm light".to_string(),
desc: "Like around 2700 Kelvin".to_string(),
}),
Box::new(Item {
title: "The vernal equinox".to_string(),
desc: "The autumnal equinox is pretty good too".to_string(),
}),
Box::new(Item {
title: "Gaffer’s tape".to_string(),
desc: "Basically sticky fabric".to_string(),
}),
Box::new(Item {
title: "Terrycloth".to_string(),
desc: "In other words, towel fabric".to_string(),
}),
];
let mut m = Model {
list: list::new(items, Box::new(list::new_default_delegate()), 0, 0),
};
m.list.title = "My Fave Things".to_string();
m
}
}
impl ModelTrait for Model {
fn init(&self) -> Cmd {
None
}
fn update(&mut self, msg: &dyn Msg) -> Cmd {
if let Some(k) = msg.as_any().downcast_ref::<KeyPressMsg>() {
if k.0.to_string() == "ctrl+c" {
return quit();
}
}
if let Some(ws) = msg.as_any().downcast_ref::<WindowSizeMsg>() {
let (h, v) = doc_style().get_frame_size();
self.list.set_size(ws.width - h, ws.height - v);
return None;
}
self.list.update(msg)
}
fn view(&self) -> View {
let mut v = View::new(&doc_style().render(&self.list.view()));
v.alt_screen = true;
v
}
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let p = Program::new(Model::new());
p.run()?;
Ok(())
}