linebender / linebender/druid

Best Practices for List Views and Lenses

Open
#1,175 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Rust
Stars
9.7k
Forks
565
PR merge metrics
No merged PRs in 30d

Description

Hi,
I am taking inspiration from the list example to build a slightly more complicated example but I run into a few conceptual issues. I am especially interested in the last part where list has shared data to be able to remove elements (redacted a bit for clarity):

List::new(|| {
    Flex::row()
        .with_child(
            Label::new(|(_, item): &(Vector<u32>, u32), _env: &_| {
                format!("List item #{}", item)
            })
        )
        .with_child(
            Button::new("Delete")
                .on_click(|_ctx, (shared, item): &mut (Vector<u32>, u32), _env| {
                    shared.retain(|v| v != item);
                })
        )
}))
.vertical()
.lens(lens::Id.map(
    |d: &AppData| (d.right.clone(), d.right.clone()),
    |d: &mut AppData, x: (Vector<u32>, Vector<u32>)| {
        d.right = x.0
    },
)

(A) First, this list only depends on AppData.right, so I'd like it to be globally lensed to that, i.e. either add .lens(AppData.right) at the end or replace lens::Id.map with AppData.right.map. This works:

.lens(
    |d: &Vector<u32>| (d.clone(), d.clone()),
    |d: &mut Vector<u32>, x: (Vector<u32>, Vector<u32>)| {
        *d = x.0
    },
)
.lens(AppData::right) // or AppData::right.map in the lens above

But is there a way to "automate" this unit Vector<T> => (Vector<T>,Vector<T>)? If I have several dynamic list I'll rewrite it many times.

(B) Let's say now AppData.right is a Vector<Stuff>. I have an impl Wiget<Stuff> object that I want to use in lieu of the Label of the example. How can I lens the state (Vector<Stuff>, Stuff) into just Stuff more elegantly that by writing a dedicated lens from scratch?

Once solved I would add it to the list.rs example I think it'd be worth sharing!

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with druid/examples/list.rs and the lens::Id.map and AppData::right usages shown in the issue. Review the existing list and lens APIs, then determine how the A and B patterns should be documented or demonstrated; done means a decided approach is captured in an updated list example.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
desktop, frontend
Issue type
Documentation
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.