use envision::prelude::*;
struct TreemapApp;
#[derive(Clone)]
struct State {
treemap: TreemapState,
}
#[derive(Clone, Debug)]
enum Msg {
Quit,
Treemap(TreemapMessage),
}
fn build_disk_usage() -> TreemapNode {
TreemapNode::new("disk", 0.0)
.with_child(
TreemapNode::new("src", 0.0)
.with_color(Color::Blue)
.with_child(TreemapNode::new("main.rs", 45.0).with_color(Color::Cyan))
.with_child(TreemapNode::new("lib.rs", 32.0).with_color(Color::LightBlue))
.with_child(
TreemapNode::new("component", 0.0)
.with_color(Color::Blue)
.with_child(TreemapNode::new("mod.rs", 28.0).with_color(Color::Cyan))
.with_child(
TreemapNode::new("treemap.rs", 22.0).with_color(Color::LightBlue),
)
.with_child(
TreemapNode::new("heatmap.rs", 18.0).with_color(Color::LightCyan),
),
),
)
.with_child(
TreemapNode::new("docs", 0.0)
.with_color(Color::Green)
.with_child(TreemapNode::new("guide.md", 15.0).with_color(Color::LightGreen))
.with_child(TreemapNode::new("api.md", 12.0).with_color(Color::Green)),
)
.with_child(
TreemapNode::new("tests", 0.0)
.with_color(Color::Yellow)
.with_child(TreemapNode::new("integration.rs", 20.0).with_color(Color::LightYellow))
.with_child(TreemapNode::new("unit.rs", 14.0).with_color(Color::Yellow)),
)
.with_child(TreemapNode::new("Cargo.toml", 8.0).with_color(Color::Magenta))
.with_child(TreemapNode::new("README.md", 5.0).with_color(Color::LightMagenta))
}
impl App for TreemapApp {
type State = State;
type Message = Msg;
fn init() -> (State, Command<Msg>) {
let treemap = TreemapState::new()
.with_root(build_disk_usage())
.with_title("Disk Usage (KB)")
.with_show_values(true);
(State { treemap }, Command::none())
}
fn update(state: &mut State, msg: Msg) -> Command<Msg> {
match msg {
Msg::Quit => Command::quit(),
Msg::Treemap(treemap_msg) => {
state.treemap.update(treemap_msg);
Command::none()
}
}
}
fn view(state: &State, frame: &mut Frame) {
let theme = Theme::default();
let area = frame.area();
Treemap::view(&state.treemap, &mut RenderContext::new(frame, area, &theme));
}
fn handle_event(event: &Event) -> Option<Msg> {
if let Some(key) = event.as_key() {
if let Key::Char('q') = key.code {
return Some(Msg::Quit);
}
}
None
}
fn handle_event_with_state(state: &State, event: &Event) -> Option<Msg> {
if let Some(msg) =
Treemap::handle_event(&state.treemap, event, &EventContext::new().focused(true))
{
return Some(Msg::Treemap(msg));
}
None
}
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut vt = Runtime::<TreemapApp, _>::virtual_builder(60, 16).build()?;
println!("=== Treemap Example ===\n");
vt.tick()?;
println!("Disk usage treemap:");
println!("{}\n", vt.display());
vt.send(Event::key(Key::Right));
vt.tick()?;
println!("After selecting next sibling:");
println!("{}\n", vt.display());
vt.send(Event::key(Key::Left));
vt.tick()?;
vt.send(Event::key(Key::Enter));
vt.tick()?;
println!("After zooming into 'src':");
println!("{}\n", vt.display());
vt.send(Event::key(Key::Esc));
vt.tick()?;
println!("After zooming out:");
println!("{}\n", vt.display());
Ok(())
}