cursive icon indicating copy to clipboard operation
cursive copied to clipboard

Still in Active Development?

Open tmollov opened this issue 8 months ago • 6 comments

Hello @gyscos ,

Is this library in active development? I have some improvements (missing functions in the code, in my opinion) and would like to contribute.

tmollov avatar Jul 23 '25 19:07 tmollov

Hi!

I'm still working on the project, but I've been quite busy with life lately, so the pace certainly slowed down a bit.

That being said, contributions are absolutely welcome!

gyscos avatar Jul 23 '25 19:07 gyscos

Thanks for the fast response @gyscos

I was thinking of adding a new method for LinearLayout: there is find_child_from_name function But no get_child_with_name for example.

I'm still exploring and learning it, but lack of similar function got my attention. IDK is this intentional? i think similar function would reduce boilerplate where users would need to call first find_child_from_name then get_child with usize from it and so on.

tmollov avatar Jul 24 '25 19:07 tmollov

I don't think there's a big reason. It was more general to return the index than the view itself (for example if you then want to move the focus, or remove it from the layout).

Also if you just need to get the view, there is already find_name from the Finder trait. I added find_child_from_name because find_name didn't quite cover these use cases where you need the index.

gyscos avatar Jul 24 '25 19:07 gyscos

Also, note that find_child_from_name returns the index of the linear layout's child that contains the given named view.

That child could itself be a layout, and the named view could be nested further down.

In that case, find_name would return the actual named view, while chaining find_child_from_name and get_child would just return the direct child of the top linear layout that contains the named view.

For example, with this layout:

LinearLayout:
    with:
        - name: outer
    children:
        - TextView: Foo
        - LinearLayout:
            with:
                - name: inner
            children:
                - TextView:
                    content: Bar
                    with:
                        - name: bar
                - Button:
                    label: Click me

Given the "outer" LinearLayout, calling find_name("bar") will return the TextView itself. But find_child_from_name will return index 1, and therefore calling get_child (or your proposed get_child_from_name) would return the "inner" linear layout.

When adding this function, I felt like this was a bit of a niche use-case (you often want either the actual named view, or just the index to alter the list or change focus). I think it didn't feel worth it having a dedicated method to get that direct-child view, but I might have been wrong.

In your case, what are you interested in exactly?

gyscos avatar Jul 24 '25 20:07 gyscos

Hi again, find_name did the job for me.

I created a phonebook CLI app in Python back then, so to get started with Cursive decided to recreate it. Just usually CRUD stuff - show all / add / edit / delete and etc.

I do add and edit with 1 view actually: ` ... let mut first_name_view = LinearLayout::horizontal();

first_name_view.add_child(TextView::new("First name: "));

first_name_view.add_child(EditView::new().with_name("first-name-edit").fixed_width(30)); ... ` Then I wanted a reference to EditView in order to set new content for that contact that I want to edit, so I looked at how to get it. I think I got confused bc Layout isn't an array, so I was searching for a function like 'get_child_with_name' or similar, which is why I created that issue :smiley:

Here is my function: PASTEBIN

I'm coming from C#/JS background and am still confused about some stuff in Rust, so thanks for your time :thumbsup:

tmollov avatar Jul 25 '25 10:07 tmollov

Yes, looks like you want find_name here :)

As a bonus, with the "recent" builder module, you could define your layout separately from your source, for example in yaml:

LinearLayout:
  children:
    - LinearLayout:
        orientation: horizontal
        children:
          - TextView: "First name: "
          - EditView:
              with:
                - name: first-name-edit
                - fixed-width: 30
    - LinearLayout:
        orientation: horizontal
        children:
          - TextView: "Last name: "
          - EditView:
            with:
              - name: last-name-edit
              - fixed-width: 30
    - LinearLayout:
        orientation: horizontal
        children:
          - TextView: "Phone: "
          - EditView:
              with:
                - name: phone-edit
                - fixed-width: 30
    - LinearLayout:
        orientation: horizontal
        children:
          - TextView: "Email: "
          - EditView:
            with:
              - name: email-edit
              - fixed-width: 30

You'd then load it from rust:

let layout_text = std::fs::read("layout.yaml").unwrap() ;  // Or include_str! for compile-time inclusion
let layout_data = serde_yaml::from_str(&layout_text).unwrap();  // You could also use json or toml or anything serde supports

let context = cursive::builder::Context::new();
let layout = context.build(&layout_data).unwrap();

// Now you can use `layout` to find views in there, ...
let mut first_name_edit = layout
    .find_name::<EditView>("first-name-edit")
    .unwrap();

(Of course it doesn't always make sense to split the layout from the source, but sometimes it does, and as a bonus you can edit the layout and re-run the app without recompiling)

As another note, an alternative to find_name is call_on_name:

layout.call_on_name("first-name-edit", |e: &mut EditView| e.set_content(c.first_name));

(find_name can be a bit surprising/tricky when storing the resulting view reference, and running a closure instead makes sure you don't hold on the reference longer than you need.)

gyscos avatar Jul 25 '25 13:07 gyscos