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

TextLog with wrap set to True causes layout issues for the rest of the display #1554

Closed
davep opened this issue Jan 12, 2023 · 3 comments · Fixed by #1581
Closed

TextLog with wrap set to True causes layout issues for the rest of the display #1554

davep opened this issue Jan 12, 2023 · 3 comments · Fixed by #1581
Labels
bug Something isn't working Task

Comments

@davep
Copy link
Contributor

davep commented Jan 12, 2023

Take this code:

from random import sample

from textual.app        import App, ComposeResult
from textual.containers import Vertical, Horizontal
from textual.widgets    import Header, Footer, TextLog, Label
from textual.binding    import Binding

class ChatPane( Vertical ):

    def compose( self ) -> ComposeResult:
        """Compose the child widgets."""
        yield Label( "Title" )
        yield TextLog( wrap=True )

class FakeChatApp( App[ None ] ):

    CSS = """
    ChatPane {
        border: round cyan;
        width: 1fr;
    }

    ChatPane:focus-within {
        border: double cyan;
    }

    ChatPane Label {
        width: 1fr;
        height: 3;
        border: round red;
    }

    ChatPane TextLog {
        height: 1fr;
        width: 1fr;
    }
    """

    BINDINGS = [
        Binding( "l", "log", "Log something" ),
    ]

    def compose( self ) -> ComposeResult:
        yield Header()
        yield Vertical(
            Horizontal( ChatPane(), ChatPane(), ChatPane() ),
            Horizontal( ChatPane(), ChatPane(), ChatPane() ),
        )
        yield Footer()

    TEXT = list( set( """Python was created in the early 1990s by Guido van Rossum at Stichting
    Mathematisch Centrum (CWI, see http://www.cwi.nl) in the Netherlands
    as a successor of a language called ABC.  Guido remains Python's
    principal author, although it includes many contributions from others.

    In 1995, Guido continued his work on Python at the Corporation for
    National Research Initiatives (CNRI, see http://www.cnri.reston.va.us)
    in Reston, Virginia where he released several versions of the
    software.

    In May 2000, Guido and the Python core development team moved to
    BeOpen.com to form the BeOpen PythonLabs team.  In October of the same
    year, the PythonLabs team moved to Digital Creations, which became
    Zope Corporation.  In 2001, the Python Software Foundation (PSF, see
    https://www.python.org/psf/) was formed, a non-profit organization
    created specifically to own Python-related Intellectual Property.
    Zope Corporation was a sponsoring member of the PSF.

    All Python releases are Open Source (see http://www.opensource.org for
    the Open Source Definition).  Historically, most, but not all, Python
    Hit Return for more, or q (and Return) to quit:
    releases have also been GPL-compatible; the table below summarizes
    the various releases.""".lower().split() ) )

    def action_log( self ):
        if self.focused is not None:
            self.focused.write( " ".join( sample( self.TEXT, 50 ) ) )

if __name__ == "__main__":
    FakeChatApp().run()

It's designed to fake a chat app that one of our Discord members has been developing, where they've been having odd layout problems. To use the test app, run it up, hit tab to focus a pane, and then spam l to log some text to the focused TextLog.

At that point you should have something akin to this:

Screenshot 2023-01-12 at 15 01 35

At that point the display is fine. However, if you tab to the next pane...

Screenshot 2023-01-12 at 15 02 23

I've also found that, often, when logging more and more items in a TextLog with this, as it scrolls itself as new text is added, sometimes the final character on some lines becomes "sticky".

@davep davep added bug Something isn't working Task labels Jan 12, 2023
@github-actions
Copy link

Thank you for your issue. Give us a little time to review it.

PS. You might want to check the FAQ if you haven't done so already.

This is an automated reply, generated by FAQtory

davep added a commit to davep/textual-sandbox that referenced this issue Jan 12, 2023
@ofek
Copy link
Contributor

ofek commented Jan 16, 2023

I can also reproduce with the following (enter text in the first box then focus or tab to the next):

from textual.app import ComposeResult
from textual.containers import Container, Horizontal
from textual.screen import Screen
from textual.widget import Widget
from textual.widgets import Button, Footer, Header, Input, Label, TextLog


class LabeledInput(Horizontal):
    DEFAULT_CSS = """
    LabeledInput {
        height: 3;
    }

    LabeledInput Label {
        margin-top: 1;
        width: 1fr;
        text-align: right;
    }

    LabeledInput Input {
        width: 5fr;
    }
    """


class ConfigurationInput(Widget):
    DEFAULT_CSS = """
    ConfigurationInput Button {
        margin: 1;
        width: 100%;
    }

    ConfigurationInput TextLog {
        margin: 1;
        height: 40%;
    }
    """

    def compose(self) -> ComposeResult:
        yield LabeledInput(Label('Repo name:'), Input())
        yield LabeledInput(Label('Repo path:'), Input())
        yield TextLog()


class Configure(Screen):
    def compose(self) -> ComposeResult:
        yield Header()
        yield Footer()
        yield ConfigurationInput()

    def on_input_changed(self, event: Input.Changed) -> None:
        text_log = self.query_one(TextLog)
        text_log.clear()
        text_log.write('\n'.join(str(i) * 50 for i in range(50)) + '\n')  # No bug without trailing new line

@github-actions
Copy link

Don't forget to star the repository!

Follow @textualizeio for Textual updates.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working Task
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants