cursive_table_view icon indicating copy to clipboard operation
cursive_table_view copied to clipboard

Dynamic table

Open realtica opened this issue 4 years ago • 6 comments

Hello, is it possible to create a table at running time dynamically? or create columns at runtime??

realtica avatar Jan 28 '22 03:01 realtica

I think it's currently not possible to create a table at runtime because an enum is defining the columns. I'll probably rewrite the library in the following days/weeks to make that possible.

Builditluc avatar Apr 26 '22 10:04 Builditluc

@gyscos, it seems like you maintain(ed) this library so do know if dynamic tables are possible?

Builditluc avatar Apr 26 '22 11:04 Builditluc

Hi,

Nothing forces you to use an enum as column type. You could use really any type that implements the required traits. u32 would work too.

You may need to re-create the table if the columns change though, I have not tested altering the columns when data is already present.

Here is a simple example:

use cursive::traits::{Resizable, With};                                                                         
use cursive_table_view::{TableView, TableViewItem};                                                             
                                                                                                                
#[derive(Clone)]                                                                                                
struct Row(Vec<String>); 2 implementations                                                                      
                                                                                                                
impl TableViewItem<usize> for Row {                                                                             
    fn to_column(&self, column: usize) -> String {                                                              
        self.0[column].clone()                                                                                  
    }                                                                                                           
                                                                                                                
    fn cmp(&self, other: &Self, column: usize) -> std::cmp::Ordering {                                          
        self.0[column].cmp(&other.0[column])                                                                    
    }                                                                                                           
}                                                                                                               
                                                                                                                
fn main() {
    let n_cols = 6;                                                                                             
    let n_rows = 30;                                                                                            
    let cell_width = 20;                                                                                        
    let table = TableView::<Row, usize>::new()                                                                  
        .with(|table| {                                                                                         
            for i in 0..n_cols {                                                                                
                table.add_column(i, format!("Column {i}"), |c| c.width(cell_width));                            
            }                                                                                                   
        })                                                                                                      
        .default_column(0)                                                                                      
        .with(|table| {                                                                                         
            for j in 0..30 {                                                                                    
                table.insert_item(Row((0..n_cols)                                                               
                    .map(|i| format!("Row {j}, column {i}"))                                                    
                    .collect()));                                                                               
            }                                                                                                   
        })                                                                                                      
        .fixed_size((n_cols * (cell_width + 2), n_rows + 2)); // There is 2 cells of padding around each column 
                                                                                                                
    let mut siv = cursive::default();                                                                           
    siv.add_layer(cursive::views::Dialog::around(table));                                                       
    siv.run();                                                                                                  
}                                                                                                               

I do agree that it would be a good idea to include that as example.

In addition, the current Copy constraint on the key might be removed eventually.

gyscos avatar Apr 26 '22 20:04 gyscos

Hey, thanks for the quick response. Okay, didn't know you could use any type (because there aren't any examples without enums).

Making this an example would be nice, so it is made more obvious that you can use just about any type (that implements the required traits).

One last thing, the examples are just normal rust files, and their corresponding Cargo.toml files are missing. So if you want to run the example locally, you have to write the dependencies yourself. Is this by design? If not, I can, if you want, open a PR and make these quick changes (basically move each example into its rust project)

Builditluc avatar Apr 27 '22 04:04 Builditluc

You can run examples using cargo:

cargo run --example basic

gyscos avatar Apr 27 '22 10:04 gyscos

Okay, didn't know that. Thanks!

Builditluc avatar Apr 27 '22 11:04 Builditluc