Cursive, callback to view seems to carry not enough info

Hi everyone, I'm using cursive crate along with cursive_table_view crate.
I'm registering callback to each created table and yes, this callback is being triggered, but I believe that there is not enough info in that callback.

//The callback
    fn Enter_Fn(app: &mut cursive::Cursive, row: usize,index: usize)
    {
    //how am I suppose to know which view triggered that callback???
    }
    ////<<<later in the code
    for i in 0..10
    {
//create panels
    let mut panel_left = create_table();//see decl below, it is the same as in examples from the repo
    panel_left.set_on_submit(Enter_Fn);//register callback
    //here I have some code that defines layout etc, so the last line is "pseudo code"
    siv.add_layout(panel_left);
    }

    fn create_table() -> TableView<Foo, BasicColumn> ;//this is function that creates table
//end of code

How to know in the Enter_Fn function which table was active when the enter was pressed, that is, we are inside of the Enter_Fn callback but all we have is app, row and index but not the view which triggered that callback.

Thanks for any help

Please use a code block instead of a quote block.

```
// your code here
```

I'm not familiar with cursive and there might be a better way but it looks like that instead of calling Enter_fn directly you can call it from a lambda like

panel_left.set_on_submit(|siv, row, index| Enter_fn(siv, row, index));

Inside the lambda you have access to other local variables like panel_left or i so the lambda could call Enter_fn(siv, row, index, i, panel_left) or similar.

Most likely it won't compile without changes since passing panel_left would move the value and passing a reference will make Rust complain about lifetimes so you'll need to identify panels/views in some other way. Perhaps cursive already has something built in.

Not related but it's worth following Rust naming conventions.

@qaopm Thanks for the answer. Unfortunately it doesn't compile. Really frustrating. Simple thing yet cannot make it working.
As far as I know cursive doesn't provide that functionality which is doubly frustrating as it seems to me that the cursive library is in very early stages...

The simplest way might be to pass not the function directly, but the closure calling it:

fn enter_fn(app: &mut cursive::Cursive, row: usize, index: usize, i: usize) {
    todo!();
}

// later in the code
for i in 0..10 {
    let mut panel_left = create_table();
    // Next line does register the callback.
    panel_left.set_on_submit(|app, row, index| enter_fn(app, row, index, i));
    siv.add_layout(panel_left);
}

@Cerberuser Hi and thanks for the answer.
In enter_fn I NEED access to the panel that the callback was called on. That seems to be the tricky part.

In this case, you have to use so-called "named views". That means:

  • When creating your view, you wrap it in NamedView, preferably by importing Nameable and calling with_name.
  • Then, you pass the name into callback.
  • In callback, you invoke call_on_name on the provided Cursive instance.
  • call_on_name finds the view by name and passes the mutable reference to it into the next callback.
1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.