Created
June 24, 2021 06:31
-
-
Save lisael/35aa7a13d4bb583f924acb832b9ef30a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::fmt; | |
use druid::im::Vector; | |
use druid::widget::{Button, Either, Flex, Label, Scroll, TextBox}; | |
use druid::{AppLauncher, Data, Lens, LocalizedString, Widget, WidgetExt, WindowDesc}; | |
use druid_widget_nursery::{Tree, TreeNode}; | |
#[derive(Clone, Lens, Data)] | |
struct Taxonomy { | |
name: String, | |
editing: bool, | |
children: Vector<Taxonomy>, // this makes use of im::Vector now (can derive Data) | |
} | |
/// We use Taxonomy as a tree node, implementing both the Data and TreeNode traits. | |
impl Taxonomy { | |
fn new(name: &'static str) -> Self { | |
Taxonomy { | |
name: name.to_string(), | |
editing: false, | |
children: Vector::new(), | |
} | |
} | |
fn add_child(mut self, child: Self) -> Self { | |
self.children.push_back(child); | |
self | |
} | |
// ADDITION: add a child on a ref (as passed to the on_click closures) | |
fn add_child_ref(&mut self, child: Self) { | |
self.children.push_back(child); | |
} | |
} | |
impl Default for Taxonomy { | |
fn default() -> Self { | |
Taxonomy { | |
name: "Life".to_string(), | |
editing: false, | |
children: Vector::new(), | |
} | |
} | |
} | |
impl TreeNode for Taxonomy { | |
fn children_count(&self) -> usize { | |
self.children.len() | |
} | |
fn get_child(&self, index: usize) -> &Taxonomy { | |
&self.children[index] | |
} | |
fn get_child_mut(&mut self, index: usize) -> &mut Taxonomy { | |
&mut self.children[index] | |
} | |
} | |
impl fmt::Display for Taxonomy { | |
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
f.write_str(&self.name) | |
} | |
} | |
pub fn main() { | |
// Create the main window | |
let main_window = WindowDesc::new(ui_builder()) | |
.title(LocalizedString::new("tree-demo-window-title").with_placeholder("Tree Demo")); | |
// Set our initial data. | |
// This is an extract from https://en.wikipedia.org/wiki/Linnaean_taxonomy | |
let taxonomy = Taxonomy::new("Life") | |
.add_child( | |
Taxonomy::new("Animalia") | |
.add_child( | |
Taxonomy::new("Aves") | |
.add_child(Taxonomy::new("Accipitres")) | |
.add_child(Taxonomy::new("Picae")) | |
.add_child(Taxonomy::new("Passeres")), | |
) | |
.add_child( | |
Taxonomy::new("Amphibia") | |
.add_child(Taxonomy::new("Reptiles")) | |
.add_child(Taxonomy::new("Serpentes")) | |
.add_child(Taxonomy::new("Nantes")), | |
) | |
.add_child(Taxonomy::new("Pisces")) | |
.add_child(Taxonomy::new("Insecta")), | |
) | |
.add_child( | |
Taxonomy::new("Vegetalia") | |
.add_child(Taxonomy::new("Monandria")) | |
.add_child(Taxonomy::new("Diandria")) | |
.add_child(Taxonomy::new("Heptandria")), | |
) | |
.add_child( | |
Taxonomy::new("Mineralia") | |
.add_child(Taxonomy::new("Petræ")) | |
.add_child(Taxonomy::new("Fossilia")) | |
.add_child(Taxonomy::new("Vitamentra")), | |
); | |
// start the application | |
AppLauncher::with_window(main_window) | |
.log_to_console() | |
.launch(taxonomy) | |
.expect("launch failed"); | |
} | |
fn ui_builder() -> impl Widget<Taxonomy> { | |
Scroll::new(Tree::new(|t: &Taxonomy| { | |
// ADDITION: use an Either to build the inner widget, bound to the editing status | |
Either::new( | |
|data, _env| (*data).editing, | |
Flex::row() | |
.with_child( | |
TextBox::new() | |
.with_placeholder("new item") | |
.lens(Taxonomy::name), | |
) | |
.with_child( | |
Button::new("Add").on_click(|ctx, data: &mut Taxonomy, _env| { | |
println!("save {}", data.name); | |
data.editing = false; | |
// ctx.children_changed(); | |
// ctx.request_paint(); | |
println!("done."); | |
}), | |
), | |
Flex::row() | |
.with_child(Label::new(t.name.as_str())) | |
.with_child( | |
Button::new("Add child").on_click(|ctx, data: &mut Taxonomy, _env| { | |
println!("create child of {}", data.name); | |
data.add_child_ref({ | |
let mut child = Taxonomy::new(""); | |
child.editing = true; | |
child | |
}); | |
// I tried to request_* almost anything here | |
// ctx.children_changed(); | |
// ctx.request_paint(); | |
println!("done."); | |
}), | |
), | |
) | |
})) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment