-
Notifications
You must be signed in to change notification settings - Fork 566
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adding Examples and documentation for List Widget #2302
base: master
Are you sure you want to change the base?
Changes from all commits
79e1ce7
5dc46b4
f840036
8a35fdc
660383b
9bc8c26
6297c5a
38fae40
93d508b
2b525ab
7b62391
c82bee7
6cef30a
3c27c6a
6cf721f
b46442f
6ad97f3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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<String>, | ||
/// } | ||
/// ``` | ||
/// ## Create initial State | ||
/// | ||
/// ``` | ||
/// # use druid::{ Data, Lens}; | ||
/// # use druid::im::Vector; | ||
/// # #[derive(Clone, Data, Lens)] | ||
/// # struct AppState { | ||
/// # list_data: Vector<String>, | ||
/// # } | ||
/// 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<String>, | ||
/// # } | ||
/// fn root() -> impl Widget<AppState> { | ||
/// let list = List::new(list_item) | ||
/// .lens(AppState::list_data); | ||
/// list | ||
/// } | ||
/// | ||
/// fn list_item() -> impl Widget<String> { | ||
/// let label = Label::new(|data: &String, _env: &Env| | ||
/// data.clone()); | ||
/// label | ||
/// } | ||
/// ``` | ||
Comment on lines
+52
to
+100
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This whole example seems way too big to me. It's the example equivalent of an integration test, where you'd want a unit test. I'd recommend skipping the |
||
/// ## 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<String>, | ||
/// # } | ||
/// # fn list_item() -> impl Widget<String> { | ||
/// # let label = Label::new(|data: &String, _env: &Env| | ||
/// # data.clone()); | ||
/// # label | ||
/// # } | ||
/// fn root() -> impl Widget<AppState> { | ||
/// 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<InnerState>, | ||
/// } | ||
/// | ||
/// #[derive(Clone, Data, Lens)] | ||
/// struct InnerState { | ||
/// name: String, | ||
/// } | ||
/// | ||
/// fn root() -> impl Widget<AppState> { | ||
/// let list = List::new(list_item) | ||
/// .lens(AppState::list_data); | ||
/// list | ||
/// } | ||
/// | ||
/// fn list_item() -> impl Widget<InnerState> { | ||
/// let label = Label::new(|data: &InnerState, _env: &Env| | ||
/// data.name.clone()); | ||
/// label | ||
/// } | ||
/// ``` | ||
Comment on lines
+125
to
+152
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think you should remove that part, or at least make it way shorter. That fact that widgets can be compose doesn't need to be documented in every container widget. |
||
/// [`im`]: https://docs.rs/druid/0.6.0/druid/im/index.html | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the link I am referring to in the description. is there a way to do it like the flex crate below? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. From my tests, it seems that |
||
/// [`Flex`]: crate::widget::Flex | ||
/// [`Vector`]: https://docs.rs/druid/0.6.0/druid/im/vector/index.html | ||
/// [`Scroll`]: crate::widget::Scroll | ||
pub struct List<T> { | ||
closure: Box<dyn Fn() -> Box<dyn Widget<T>>>, | ||
children: Vec<WidgetPod<T, Box<dyn Widget<T>>>>, | ||
|
@@ -45,6 +165,41 @@ pub struct List<T> { | |
impl<T: Data> List<T> { | ||
/// 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. | ||
/// | ||
Comment on lines
+168
to
+171
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This part seems superfluous. I think you can assume the vast majority of Rust users will be familiar with how closures work. (And if they aren't, this isn't the place to explain them) |
||
/// # 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<String>, | ||
/// # } | ||
/// fn root() -> impl Widget<AppState> { | ||
/// let list = List::new(list_item) | ||
/// .lens(AppState::list_data); | ||
/// list | ||
/// } | ||
/// | ||
/// fn list_item() -> impl Widget<String> { | ||
/// 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<AppState> { | ||
/// let list = List::new(|| | ||
/// Label::new(|data: &String, _env: &Env| | ||
/// data.clone())) | ||
/// .lens(AppState::list_data); | ||
/// list | ||
/// } | ||
Comment on lines
+193
to
+201
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can probably remove the |
||
/// ``` | ||
pub fn new<W: Widget<T> + 'static>(closure: impl Fn() -> W + 'static) -> Self { | ||
List { | ||
closure: Box::new(move || Box::new(closure())), | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Marking the code as toml gets you better highlighting.