Textualize / textual

The lean application framework for Python. Build sophisticated user interfaces with a simple Python API. Run your apps in the terminal and a web browser.
https://textual.textualize.io/
MIT License
25.65k stars 788 forks source link

Transitions (offset for example) don't work when also going from "display: none" to a displayed state #1124

Open epi052 opened 2 years ago

epi052 commented 2 years ago

Please give a brief but clear explanation of what the issue is. Let us know what the behaviour you expect is, and what is actually happening. Let us know what operating system you are running on, and what terminal you are using.

current: When opening either dock for the first time, there is no animation. The animation only happens after the first in/out of either dock. This happens with inline CSS as well as a CSS file. expected: the docks should be animated on every open/close, including the first

Feel free to add screenshots and/or videos. These can be very helpful!

https://user-images.githubusercontent.com/43392618/200075228-33bf9c1a-9539-4f83-9665-628a85ecd72a.mp4

If you can, include a complete working example that demonstrates the bug. Please check it can run without modifications.

class Demo(App):
    TITLE = "Demonstration"
    BINDINGS = [
        ("s", "toggle_sidebar", "Sidebar"),
        ("b", "toggle_bottombar", "Bottombar"),
    ]
    CSS = """
    Screen {
        layout: grid;
        grid-size: 2 5;
    }

    .box {
        height: 100%;
        border: round white;
    }

    #left-main {
        row-span: 5;
    }

    #right-main {
        row-span: 5;
    }

    #sidebar {
        display: none;
        offset-x: -100%;
    }

    Demo.-show-sidebar #sidebar {
        display: block;
        dock: left;

        border: round yellow;

        height: 100%;
        max-width: 33%;
        margin-bottom: 1;

        transition: offset 500ms in_out_cubic;
        offset-x: 0;
    }

    #bottombar {
        display: none;
        offset-y: 100%;
    }

    Demo.-show-bottombar #bottombar {
        display: block;
        dock: bottom;

        border: round red;

        max-height: 33%;
        width: 100%;
        margin-bottom: 1;

        transition: offset 500ms in_out_cubic;
        offset-y: 0;
    }

    Demo.-show-sidebar.-show-bottombar #bottombar {
        offset-x: 47%;
        width: 68%;
    }

    """

    def compose(self) -> ComposeResult:
        # yield Header()
        yield Static(classes="box", id="left-main")
        yield Static(classes="box", id="right-main")
        yield Static(classes="box", id="sidebar")
        yield Static(classes="box", id="bottombar")
        yield Footer()

    def action_toggle_sidebar(self) -> None:
        if "-show-sidebar" in self.classes:
            self.remove_class("-show-sidebar")
        else:
            self.add_class("-show-sidebar")

    def action_toggle_bottombar(self) -> None:
        if "-show-bottombar" in self.classes:
            self.remove_class("-show-bottombar")
        else:
            self.add_class("-show-bottombar")

if __name__ == "__main__":
    Demo().run()
davep commented 2 years ago

(keeping the suggested code in #1122 in mind as it's a different aspect of the same issue)

Speaking with @willmcgugan, and if I properly comprehended and am correctly recalling the explanation, it looks like the issue here isn't so much about the widget being docked, it's more about it starting out as being display: none, so the animation doesn't really have a starting position.

While there's no timescale for it, I'll add it to our backlog to look at as Will seemed to think there could be a way to handle this.

epi052 commented 2 years ago

that makes sense. The reason I was using the display:none is that even with an initial offset that's (in my mind) 'off-screen' there's still empty space taken up by the widget.

thanks again for the help!

davep commented 2 years ago

See also #1123 as something very closely related.

willmcgugan commented 1 year ago

This might have to wait until we review the animation system.

Animations should be set per rule, rather than per widget.

Some preliminary work here https://github.com/Textualize/textual/pull/1740