From 318a436ab5c28e33904cb3618dee4e46d85ad073 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Mon, 8 Jan 2024 15:17:25 +0000 Subject: [PATCH 1/5] Allow Tab.label to be set and have the display redraw In support of a better interface for #3901. --- src/textual/widgets/_tabs.py | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/src/textual/widgets/_tabs.py b/src/textual/widgets/_tabs.py index 123ade6c13..0123e17688 100644 --- a/src/textual/widgets/_tabs.py +++ b/src/textual/widgets/_tabs.py @@ -5,6 +5,7 @@ from typing import ClassVar import rich.repr +from rich.console import RenderableType from rich.style import Style from rich.text import Text, TextType @@ -143,6 +144,9 @@ class Disabled(TabMessage): class Enabled(TabMessage): """A tab was enabled.""" + class Relabelled(TabMessage): + """A tab was relabelled.""" + def __init__( self, label: TextType, @@ -159,9 +163,23 @@ def __init__( classes: Space separated list of class names. disabled: Whether the tab is disabled or not. """ - self.label = Text.from_markup(label) if isinstance(label, str) else label super().__init__(id=id, classes=classes, disabled=disabled) - self.update(label) + self._label: Text + self.label = label + + @property + def label(self) -> Text: + """The label for the tab.""" + return self._label + + @label.setter + def label(self, label: TextType) -> None: + self._label = Text.from_markup(label) if isinstance(label, str) else label + self.update(self._label) + + def update(self, renderable: RenderableType = "") -> None: + self.post_message(self.Relabelled(self)) + return super().update(renderable) @property def label_text(self) -> str: @@ -693,6 +711,11 @@ def _on_tab_enabled(self, event: Tab.Enabled) -> None: event.stop() self.post_message(self.TabEnabled(self, event.tab)) + def _on_tab_relabelled(self, event: Tab.Relabelled) -> None: + """Redraw the highlight when tab is relabelled.""" + event.stop() + self._highlight_active() + def disable(self, tab_id: str) -> Tab: """Disable the indicated tab. From 774f99763179db50fd966ea8e4f5fb72df96d812 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Mon, 8 Jan 2024 15:28:04 +0000 Subject: [PATCH 2/5] Add a test for low-level tab relabelling --- tests/test_tabs.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/test_tabs.py b/tests/test_tabs.py index 1269820115..32e626cefb 100644 --- a/tests/test_tabs.py +++ b/tests/test_tabs.py @@ -13,6 +13,14 @@ async def test_tab_label(): assert Tab("Pilot").label_text == "Pilot" +async def test_tab_relabel(): + """It should be possible to relabel a tab.""" + tab = Tab("Pilot") + assert tab.label_text == "Pilot" + tab.label = "Aeryn" + assert tab.label_text == "Aeryn" + + async def test_compose_empty_tabs(): """It should be possible to create an empty Tabs.""" From fc3714ab5c98324d126e452fdd16fc55293fb512 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Mon, 8 Jan 2024 15:43:46 +0000 Subject: [PATCH 3/5] Add some testing for tab label updates --- .../__snapshots__/test_snapshots.ambr | 159 ++++++++++++++++++ .../snapshot_apps/tab_rename.py | 16 ++ tests/snapshot_tests/test_snapshots.py | 5 + 3 files changed, 180 insertions(+) create mode 100644 tests/snapshot_tests/snapshot_apps/tab_rename.py diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots.ambr b/tests/snapshot_tests/__snapshots__/test_snapshots.ambr index 5a2d500a4d..cbf0099dca 100644 --- a/tests/snapshot_tests/__snapshots__/test_snapshots.ambr +++ b/tests/snapshot_tests/__snapshots__/test_snapshots.ambr @@ -32386,6 +32386,165 @@ ''' # --- +# name: test_tab_rename + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TabRenameApp + + + + + + + + + + + This is a much longer label for the tab011222333344444 + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + TabPane#test + + + + + + + + + + + + + + + + + + + + + + + + ''' +# --- # name: test_tabbed_content ''' diff --git a/tests/snapshot_tests/snapshot_apps/tab_rename.py b/tests/snapshot_tests/snapshot_apps/tab_rename.py new file mode 100644 index 0000000000..568c37bc50 --- /dev/null +++ b/tests/snapshot_tests/snapshot_apps/tab_rename.py @@ -0,0 +1,16 @@ +from textual.app import App, ComposeResult +from textual.widgets import TabbedContent, TabPane + +class TabRenameApp(App[None]): + + def compose(self) -> ComposeResult: + with TabbedContent(): + yield TabPane("!", id="test") + for n in range(5): + yield TabPane(str(n) * (n+1)) + + def on_mount(self) -> None: + self.query_one(TabbedContent).get_tab("test").label = "This is a much longer label for the tab" + +if __name__ == "__main__": + TabRenameApp().run() diff --git a/tests/snapshot_tests/test_snapshots.py b/tests/snapshot_tests/test_snapshots.py index 3b2bad8992..63e5d93026 100644 --- a/tests/snapshot_tests/test_snapshots.py +++ b/tests/snapshot_tests/test_snapshots.py @@ -979,3 +979,8 @@ def test_nested_specificity(snap_compare): """Test specificity of nested rules is working.""" # https://github.com/Textualize/textual/issues/3961 assert snap_compare(SNAPSHOT_APPS_DIR / "nested_specificity.py") + + +def test_tab_rename(snap_compare): + """Test setting a new label for a tab amongst a TabbedContent.""" + assert snap_compare(SNAPSHOT_APPS_DIR / "tab_rename.py") From 7eb089c7caaace8318b8abfb713637cd01cc16d1 Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Mon, 8 Jan 2024 15:46:15 +0000 Subject: [PATCH 4/5] Update the ChangeLog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 178b1b74a4..4a0ca3d3ea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Breaking change: `DOMNode.has_pseudo_class` now accepts a single name only https://github.com/Textualize/textual/pull/3970 - Made `textual.cache` (formerly `textual._cache`) public https://github.com/Textualize/textual/pull/3976 +- `Tab.label` can now be used to change the label of a tab ### Added From d9605d2b80cc7172290b729dea2be7785598802c Mon Sep 17 00:00:00 2001 From: Dave Pearson Date: Mon, 8 Jan 2024 15:54:49 +0000 Subject: [PATCH 5/5] Link to the PR --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a0ca3d3ea..626d79f492 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Breaking change: `DOMNode.has_pseudo_class` now accepts a single name only https://github.com/Textualize/textual/pull/3970 - Made `textual.cache` (formerly `textual._cache`) public https://github.com/Textualize/textual/pull/3976 -- `Tab.label` can now be used to change the label of a tab +- `Tab.label` can now be used to change the label of a tab https://github.com/Textualize/textual/pull/3979 ### Added