Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to always "scroll to bottom"/"crop from top where necessary"? #45

Closed
lspitzner opened this issue Mar 9, 2016 · 3 comments
Closed

Comments

@lspitzner
Copy link

I would like behaviour where lines grow from bottom to top, for a greedy widget. lets say there is space for 10 lines. If there is one line of content, i want it to be at the bottom. if there are 20 lines of contents, i want 11-20 displayed.

I have played around with viewports/adding empty lines/translating; nothing gave this exact behaviour. closest was invoking visible on the bottom line; but then the viewport remains translated even if the available space increases (again). (Also, this solution feels kinda hacky.)

@jtdaugherty
Copy link
Owner

If you specifically want to work with lines that are strings, a custom widget such as the following can do what you want. If you want this behavior to work for arbitrary widgets, a viewport will be necessary and in that case rather than using visibility functions you'll need to call vScrollToEnd in your event handler whenever the window is resized (or whenever conditions change enough that you'd want to re-orient your cropped area).

module Main where
import Control.Lens ((^.))
import Control.Applicative ((<$>))
import Brick

alignBottom :: [String] -> Widget
alignBottom theLines =
    Widget Greedy Greedy $ do
        ctx <- getContext
        let numToDrop = max 0 $ length theLines - ctx^.availHeightL
            numEmptyLines = max 0 $ ctx^.availHeightL - length theLines
            linesWidget = str $ unlines $ drop numToDrop theLines
            emptyLines = vLimit numEmptyLines $ fill ' '
        render $ emptyLines <=> linesWidget

ui :: Widget
ui = alignBottom $ ("line " ++) <$> show <$> [1..20]

main :: IO ()
main = simpleMain ui

@lspitzner
Copy link
Author

Oh great, that works perfectly. I could have looked into custom widgets myself, but had assumed there would be a solution using the existing combinators.

Thanks for the quick reply!

@jtdaugherty
Copy link
Owner

Great! I definitely want the built-in combinators to make writing custom widgets unnecessary, but there will definitely be cases where that's the only approach.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants