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

Incorrect Overlay height calculations #471

Open
mfncooper opened this issue Apr 6, 2021 · 1 comment
Open

Incorrect Overlay height calculations #471

mfncooper opened this issue Apr 6, 2021 · 1 comment

Comments

@mfncooper
Copy link
Contributor

Description:

If you use an Overlay with a valign of 'middle' and height of 'pack', the height calculations are incorrect if there is a Text widget (for example) with multiple lines of text. This manifests in two distinct ways. One, the vertical alignment does not come out properly, and the overlay widget is "pushed down" below where it should be on top of its parent. Two, mouse clicks on any buttons below the long text item no longer work, because the click position is not being mapped properly. The overlay widget is rendered correctly, but in the wrong place, vertically, and without working mouse clicks below the long text.

From a brief foray into the code - I am no expert on Urwid's layout code, by any stretch of the imagination - it looks to me as if the calculation for the height of the widget, as used for alignment and mouse events, is being based on a width that is the full screen width, instead of the overlay's specified width. This results in the long text item being measured as 1 row high, which means that the total height used in these two calculations is short by however many extra rows the long text actually needs.

Affected versions (if applicable)

2.1.2

@mfncooper
Copy link
Contributor Author

Here's some sample code that illustrates the issue. Using keys to move between fields and "click" on the button works fine for both small and large examples. Using the mouse works fine in the small example. In the large example, it's clear that vertical centering does not work, and while the mouse can be used to move between Field 1 and Field 2, attempting to click on the button does not work.

import urwid

def show_overlay(text):
    w_button = urwid.Button('ok')
    urwid.connect_signal(w_button, 'click', close)
    w_body = urwid.LineBox(urwid.Pile([
        urwid.Edit(caption="Field 1: ", edit_text='hello'),
        urwid.Edit(caption="Field 2: ", edit_text='world'),
        urwid.Text(text),
        w_button
    ]))
    w_overlay = urwid.Overlay(
        w_body,
        main,
        align = 'center',
        width = 40,
        valign = 'middle',
        height =  'pack'
    )
    loop.widget = w_overlay

def show_small():
    show_overlay("The short version")

def show_large():
    text = ("dui sapien eget mi proin sed libero enim sed faucibus turpis in "
        "eu mi bibendum neque egestas congue quisque egestas diam in arcu "
        "cursus euismod quis viverra nibh cras pulvinar mattis nunc sed "
        "blandit libero volutpat sed cras ornare arcu dui vivamus arcu felis "
        "bibendum ut tristique et egestas quis ipsum suspendisse ultrices "
        "vestibulum rhoncus est pellentesque elit ullamcorper dignissim cras "
        "tincidunt lobortis feugiat vivamus at augue eget arcu dictum varius "
        "duis at consectetur lorem donec massa sapien faucibus et molestie ac "
        "feugiat sed lectus vestibulum mattis ullamcorper velit sed ullamcorper "
        "morbi tincidunt ornare massa eget egestas purus viverra accumsan in")
    show_overlay(text)

def close(button):
    loop.widget = main
    main._invalidate()

def handle_input(key):
    if key in ('S', 's'):
        show_small()
    elif key in ('L', 'l'):
        show_large()
    elif key in ('Q', 'q'):
        raise urwid.ExitMainLoop()

header = urwid.Text("Urwid Issue #471", align='center')
text = "Press S for small example, L for large (broken) example, Q to exit."
body = urwid.LineBox(urwid.Filler(urwid.Text(text, align='center')))
main = urwid.Frame(body, header=header)

loop = urwid.MainLoop(main, unhandled_input=handle_input)
loop.run()

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

No branches or pull requests

2 participants