diff --git a/CHANGELOG.md b/CHANGELOG.md index d6cbcae67c..637dcdf0e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -151,6 +151,7 @@ You can find its changes [documented below](#070---2021-01-01). - Fix `Controller` links for `Click` ([#2158] by [@yrns]) - Delete inaccurate line for `KeyEvent` ([#2247] by [@amtep]) - Added examples in `TextBox` ([#2284] by [@ThomasMcandrew]) +- Added examples in `List` ([#2302] by [@ThomasMcandrew]) ### Examples - Add readme ([#1423] by [@JAicewizard]) @@ -867,6 +868,7 @@ Last release without a changelog :( [#2247]: https://github.com/linebender/druid/pull/2247 [#2274]: https://github.com/linebender/druid/pull/2274 [#2284]: https://github.com/linebender/druid/pull/2284 +[#2302]: https://github.com/linebender/druid/pull/2302 [Unreleased]: https://github.com/linebender/druid/compare/v0.7.0...master [0.7.0]: https://github.com/linebender/druid/compare/v0.6.0...v0.7.0 diff --git a/druid/src/widget/list.rs b/druid/src/widget/list.rs index 340da1637b..5a174029b3 100644 --- a/druid/src/widget/list.rs +++ b/druid/src/widget/list.rs @@ -34,6 +34,126 @@ use crate::{ }; /// A list widget for a variable-size collection of items. +/// For a static sized collection of items use [`Flex`]. +/// The best data structure to use with the list widget is [`Vector`] from the [`im`] feature. +/// To include the [`im`] feature, update Cargo.toml +/// ```ignore +/// [dependencies] +/// // before +/// druid = "0.7.0" +/// // after +/// druid = { version = "0.7.0", features = ["im"] } +/// ``` +/// +/// # Examples +/// +/// ## Define the data +/// +/// ``` +/// # use druid::{ Data, Lens }; +/// use druid::im::Vector; +/// #[derive(Clone, Data, Lens)] +/// struct AppState { +/// list_data: Vector, +/// } +/// ``` +/// ## Create initial State +/// +/// ``` +/// # use druid::{ Data, Lens}; +/// # use druid::im::Vector; +/// # #[derive(Clone, Data, Lens)] +/// # struct AppState { +/// # list_data: Vector, +/// # } +/// let initial_state = AppState { +/// list_data: Vector::from( +/// vec!( +/// "one".into(), +/// "two".into(), +/// "three".into(), +/// "four".into(), +/// )), +/// }; +/// ``` +/// ## Create widgets +/// +/// ``` +/// # use druid::widget::{ Label, List }; +/// # use druid::{ Data, Lens, Widget, WidgetExt, Env}; +/// # use druid::im::Vector; +/// # #[derive(Clone, Data, Lens)] +/// # struct AppState { +/// # list_data: Vector, +/// # } +/// fn root() -> impl Widget { +/// let list = List::new(list_item) +/// .lens(AppState::list_data); +/// list +/// } +/// +/// fn list_item() -> impl Widget { +/// let label = Label::new(|data: &String, _env: &Env| +/// data.clone()); +/// label +/// } +/// ``` +/// ## Scrollable List +/// Commonly a list should be able to scroll, the [`Scroll`] widget can be used to implement this +/// feature. +/// See docs for more info. +/// +/// ``` +/// # use druid::widget::{ Label, List, Scroll }; +/// # use druid::{ Data, Lens, Widget, WidgetExt, Env}; +/// # use druid::im::Vector; +/// # #[derive(Clone, Data, Lens)] +/// # struct AppState { +/// # list_data: Vector, +/// # } +/// # fn list_item() -> impl Widget { +/// # let label = Label::new(|data: &String, _env: &Env| +/// # data.clone()); +/// # label +/// # } +/// fn root() -> impl Widget { +/// let list = List::new(list_item) +/// .lens(AppState::list_data); +/// Scroll::new(list) +/// } +/// ``` +/// ## Complex widgets +/// List can be used with any complex widgets. +/// ``` +/// # use druid::widget::{ Label, List }; +/// # use druid::{ Data, Lens, Widget, WidgetExt, Env}; +/// # use druid::im::Vector; +/// #[derive(Clone, Data, Lens)] +/// struct AppState { +/// list_data: Vector, +/// } +/// +/// #[derive(Clone, Data, Lens)] +/// struct InnerState { +/// name: String, +/// } +/// +/// fn root() -> impl Widget { +/// let list = List::new(list_item) +/// .lens(AppState::list_data); +/// list +/// } +/// +/// fn list_item() -> impl Widget { +/// let label = Label::new(|data: &InnerState, _env: &Env| +/// data.name.clone()); +/// label +/// } +/// ``` +/// [`im`]: https://docs.rs/druid/0.6.0/druid/im/index.html +/// [`Flex`]: crate::widget::Flex +/// [`Vector`]: https://docs.rs/druid/0.6.0/druid/im/vector/index.html +/// [`Scroll`]: crate::widget::Scroll pub struct List { closure: Box Box>>, children: Vec>>>, @@ -45,6 +165,41 @@ pub struct List { impl List { /// Create a new list widget. Closure will be called every time when a new child /// needs to be constructed. + /// + /// The list widget can have a function passed in as a closure, or an abstract closure can also + /// be provided. + /// + /// # Example + /// ``` + /// # use druid::widget::{ Label, List }; + /// # use druid::{ Data, Lens, Widget, WidgetExt, Env}; + /// # use druid::im::Vector; + /// # #[derive(Clone, Data, Lens)] + /// # struct AppState { + /// # list_data: Vector, + /// # } + /// fn root() -> impl Widget { + /// let list = List::new(list_item) + /// .lens(AppState::list_data); + /// list + /// } + /// + /// fn list_item() -> impl Widget { + /// let label = Label::new(|data: &String, _env: &Env| + /// data.clone()); + /// label + /// } + /// + /// //This widget is the same as the two widgets above + /// //combined. + /// fn combined() -> impl Widget { + /// let list = List::new(|| + /// Label::new(|data: &String, _env: &Env| + /// data.clone())) + /// .lens(AppState::list_data); + /// list + /// } + /// ``` pub fn new + 'static>(closure: impl Fn() -> W + 'static) -> Self { List { closure: Box::new(move || Box::new(closure())),