gyscos / cursive

A Text User Interface library for the Rust programming language
MIT License
4.24k stars 240 forks source link

[Help/Suggestion] Adding floating point margins for more control #359

Open yashaslokesh opened 5 years ago

yashaslokesh commented 5 years ago

Help, or Suggestion if not possible

Problem description

I'm using a padded view to make my content easier to read. However, margins must be a usize and 1 is still a little too big for my application. Is there a way to add floating point margins?

Environment

gyscos commented 5 years ago

Hi, and thanks for the report! Cursive currently is bound to the character grid, which means it can only use a whole number of columns or rows for margins and such.

That's because it's hard, in the general case, to offset a character by a fraction of a cell (sixels might help, but are not super supported yet).

But some characters are easier to offset, namely borders. It might be possible to have a view that looks like it draws a border a fraction of a cell away from the content. We might be limited in the style of borders available, but that's an option. Basically, instead of using a full cell for a border, we use two cells where only a part of each cell is actually filled.

This will need a bit more research to find what exactly can be usable.

yashaslokesh commented 5 years ago

Okay, thank you for the reply! I might look into this further

yashaslokesh commented 5 years ago

Additionally, is there a way I can make a selection view using views as the items in the current library? SelectView and ListView both show string values. I'm working on a Reddit viewer so I want users to select a certain PostView which will then trigger an action to show the post.

yashaslokesh commented 5 years ago
let mut list = ScrollView::new(OnEventView::new(LinearLayout::vertical()).on_event_inner(
        'p',
        |l: &mut LinearLayout, _| {
            // println!("idx: {}", l.get_focus_index());

            // l.get_child_mut(l.get_focus_index()).unwrap().None
            Some(EventResult::Consumed(None))
        },
    ));

I tried the above code to check the focus index on my LinearLayout after a certain key press, but the focus index seems to reset after receiving the event. I tried on_event_inner() and on_pre_event_inner(). When I press p, the ScrollView gets reset to the top of the LinearLayout.

gyscos commented 5 years ago

I may need more context about that - focus shouldn't move by itself. Are you re-creating the LinearLayout? This might reset the index.

Note: you can also wrap each view in the LinearLayout with an event listener, rather than the LinearLayout itself; this way, you might not even need to query its focus index.

yashaslokesh commented 5 years ago

I'm not re-creating the LinearLayout, the OnEventView uses on_event_inner() to get the inner LinearLayout as an argument, and then print its focus index.

I tried wrapping the LinearLayout with an IdView and then I used call_on_id() to access the LinearLayout and print its focus, but I was still getting a value of 0 wherever I navigated on the page.

I'm trying to configure LinearLayout so it becomes like a SelectView for a list of views, so I didn't want to wrap each view inside the LinearLayout with an event listener. I thought using the up and down arrow keys on the LinearLayout would move its focus correspondingly, so then I could have an event listener for the Enter key and do some action corresponding to the selected child view.