textual icon indicating copy to clipboard operation
textual copied to clipboard

Writing to a hidden RichLog breaks table alignment

Open geoff-va opened this issue 1 year ago • 2 comments

I've got a RichLog that is often hidden and I write text to it. I'm using a Rich.Table to left/right justify two pieces of text on a single line.

This works as expected while the widget is shown.

If the widget has either visible=False or display=False set, then any text written during that time is collapsed together into a single string.

I'm not sure if this is a side effect of not having the widget displayed (no space is calculated for it so it doesn't know what sizes to use when writing the Table?) or not. If this is working as expected, might there be any way to write to the widget while it's hidden but preserve the appropriate sizing?

The following is an example of writing to the widget both while it is shown, has visible=False and display=False.

hidden-width

Example Code (same that produced gif above).

from __future__ import annotations

import random

from rich.align import Align
from rich.table import Table
from rich.text import Text
from textual.app import App, ComposeResult
from textual.widgets import RichLog


class Example(App):
    BINDINGS = [
        ("w", "write_line", "Write Line"),
        ("h", "toggle_visible", "Toggle Visibility"),
        ("d", "toggle_display", "Toggle Display"),
        ("q", "quit", "Quit"),
    ]

    DEFAULT_CSS = """
    #one  {
        border: round white;
        height: 1fr;
    }
    #two  {
        border: round white;
        height: 1fr;
    }
    """

    def compose(self) -> ComposeResult:
        log1 = RichLog(id="one")
        log1.border_title = "Log 1"
        log2 = RichLog(id="two")
        log2.border_title = "Log 2"
        yield log1
        yield log2

    def action_toggle_visible(self) -> None:
        log1 = self.query_one("#one", RichLog)
        log2 = self.query_one("#two", RichLog)

        log2.visible = not log2.visible
        log1.write(f"log2 visibility={log2.visible}")

    def action_toggle_display(self) -> None:
        log1 = self.query_one("#one", RichLog)
        log2 = self.query_one("#two", RichLog)

        log2.display = not log2.display
        log1.write(f"log2 display={log2.display}")

    def action_write_line(self) -> None:
        """Write a line to log 2"""
        log1 = self.query_one("#one", RichLog)
        log2 = self.query_one("#two", RichLog)

        left = Text("something: text on the left")
        right = Text("Stuff on the right")
        table = Table.grid(expand=True)
        table.add_row(left, Align.right(right))

        log2.write(table, expand=True)
        log1.write("Wrote to log2")


if __name__ == "__main__":
    app = Example()
    app.run()

Textual Diagnostics

Versions

Name Value
Textual 0.46.0
Rich 13.7.0

Python

Name Value
Version 3.8.10
Implementation CPython
Compiler Clang 14.0.3 (clang-1403.0.22.14.1)
Executable /Users/geoff/Documents/projects/kafka-tui/venv/bin/python

Operating System

Name Value
System Darwin
Release 23.3.0
Version Darwin Kernel Version 23.3.0: Wed Dec 20 21:30:27 PST 2023; root:xnu-10002.81.5~7/RELEASE_ARM64_T8103

Terminal

Name Value
Terminal Application vscode (1.86.0)
TERM xterm-256color
COLORTERM truecolor
FORCE_COLOR Not set
NO_COLOR Not set

Rich Console options

Name Value
size width=115, height=40
legacy_windows False
min_width 1
max_width 115
is_terminal True
encoding utf-8
max_height 40
justify None
overflow None
no_wrap False
highlight None
markup None
height None

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

geoff-va avatar Feb 05 '24 06:02 geoff-va

We found the following entry in the FAQ which you may find helpful:

Feel free to close this issue if you found an answer in the FAQ. Otherwise, please give us a little time to review.

This is an automated reply, generated by FAQtory

github-actions[bot] avatar Feb 05 '24 06:02 github-actions[bot]

I'm not sure if this is a side effect of not having the widget displayed (no space is calculated for it so it doesn't know what sizes to use when writing the Table?) or not. If this is working as expected, might there be any way to write to the widget while it's hidden but preserve the appropriate sizing?

I think you're right about Rich.Table not knowing how to calculate the column width.

Perhaps you could set table.width = log2.scrollable_content_region.width as a workaround?

TomJGooding avatar Feb 05 '24 21:02 TomJGooding

Gave it a whirl but unfortunately that doesn't seem to be working either. Looks to be writing empty lines in that case when it's not displayed. The width reported while it's hidden is 0.

image

geoff-va avatar Feb 17 '24 17:02 geoff-va

Don't forget to star the repository!

Follow @textualizeio for Textual updates.

github-actions[bot] avatar Feb 27 '24 19:02 github-actions[bot]

Just tried my example out with the latest textual (0.52.1) but unfortunately I appear to be getting the same results as before.

image

geoff-va avatar Mar 10 '24 17:03 geoff-va

The fix is in main. It will be in next week's release.

willmcgugan avatar Mar 10 '24 17:03 willmcgugan

Ah - thanks for pointing that out. I should have checked instead of assumed :)

geoff-va avatar Mar 10 '24 17:03 geoff-va