Fix scrollbar (#2024)

* Fix scrollbar

* changelog PR

* fix snapshots
This commit is contained in:
Will McGugan
2023-03-13 10:39:14 +00:00
committed by GitHub
parent fcda3c3350
commit 9c5e0336f8
7 changed files with 511 additions and 92 deletions

View File

@@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
### Fixed ### Fixed
- Fixed container not resizing when a widget is removed https://github.com/Textualize/textual/issues/2007 - Fixed container not resizing when a widget is removed https://github.com/Textualize/textual/issues/2007
- Fixes issue where the horizontal scrollbar would be incorrectly enabled https://github.com/Textualize/textual/pull/2024
### Added ### Added

View File

@@ -1,5 +1,5 @@
from textual.app import App from textual.app import App
from textual.containers import Vertical from textual.containers import Container
from textual.widgets import Label from textual.widgets import Label
TEXT = """I must not fear. TEXT = """I must not fear.
@@ -14,7 +14,7 @@ Where the fear has gone there will be nothing. Only I will remain.
class ScrollbarApp(App): class ScrollbarApp(App):
def compose(self): def compose(self):
yield Vertical(Label(TEXT * 5), classes="panel") yield Container(Label(TEXT * 5), classes="panel")
app = ScrollbarApp(css_path="scrollbar_size.css") app = ScrollbarApp(css_path="scrollbar_size.css")

View File

@@ -1010,11 +1010,11 @@ class Widget(DOMNode):
show_vertical = self.virtual_size.height > height show_vertical = self.virtual_size.height > height
# When a single scrollbar is shown, the other dimension changes, so we need to recalculate. # When a single scrollbar is shown, the other dimension changes, so we need to recalculate.
if show_vertical and not show_horizontal: if overflow_x == "auto" and show_vertical and not show_horizontal:
show_horizontal = self.virtual_size.width > ( show_horizontal = self.virtual_size.width > (
width - styles.scrollbar_size_vertical width - styles.scrollbar_size_vertical
) )
if show_horizontal and not show_vertical: if overflow_y == "auto" and show_horizontal and not show_vertical:
show_vertical = self.virtual_size.height > ( show_vertical = self.virtual_size.height > (
height - styles.scrollbar_size_horizontal height - styles.scrollbar_size_horizontal
) )

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,189 @@
from os import urandom
from random import randrange
from textual.app import App
from textual.containers import Container, Horizontal, Vertical
from textual.screen import Screen
from textual.widgets import DataTable, Header, Label
class LabeledBox(Container):
DEFAULT_CSS = """
LabeledBox {
layers: base_ top_;
width: 100%;
height: 100%;
}
LabeledBox > Container {
layer: base_;
border: round $primary;
width: 100%;
height: 100%;
layout: vertical;
}
LabeledBox > Label {
layer: top_;
offset-x: 2;
}
"""
def __init__(self, title, *args, **kwargs):
self.__label = Label(title)
super().__init__(self.__label, Container(*args, **kwargs))
@property
def label(self):
return self.__label
class StatusTable(DataTable):
def __init__(self):
super().__init__()
self.cursor_type = "row"
self.show_cursor = False
self.add_column("Foo")
self.add_column("Bar")
self.add_column("Baz")
for _ in range(50):
self.add_row(
"ABCDEFGH",
"0123456789",
"IJKLMNOPQRSTUVWXYZ",
)
class Status(LabeledBox):
DEFAULT_CSS = """
Status {
width: auto;
}
Status Container {
width: auto;
}
Status StatusTable {
width: auto;
margin-top: 1;
scrollbar-gutter: stable;
overflow-x: hidden;
}
"""
def __init__(self, name: str):
self.__name = name
self.__table = StatusTable()
super().__init__(f" {self.__name} ", self.__table)
@property
def name(self) -> str:
return self.__name
@property
def table(self) -> StatusTable:
return self.__table
class Rendering(LabeledBox):
DEFAULT_CSS = """
#issue-info {
height: auto;
border-bottom: dashed #632CA6;
}
#statuses-box {
height: 1fr;
width: auto;
}
"""
def __init__(self):
self.__info = Label("test")
super().__init__(
"",
Container(
Horizontal(self.__info, id="issue-info"),
Horizontal(*[Status(str(i)) for i in range(4)], id="statuses-box"),
id="issues-box",
),
)
@property
def info(self) -> Label:
return self.__info
class Sidebar(LabeledBox):
DEFAULT_CSS = """
#sidebar-status {
height: auto;
border-bottom: dashed #632CA6;
}
#sidebar-options {
height: 1fr;
}
"""
def __init__(self):
self.__status = Label("ok")
self.__options = Vertical()
super().__init__(
"",
Container(self.__status, id="sidebar-status"),
Container(self.__options, id="sidebar-options"),
)
@property
def status(self) -> Label:
return self.__status
@property
def options(self) -> Vertical:
return self.__options
class MyScreen(Screen):
DEFAULT_CSS = """
#main-content {
layout: grid;
grid-size: 2;
grid-columns: 1fr 5fr;
grid-rows: 1fr;
}
#main-content-sidebar {
height: 100%;
}
#main-content-rendering {
height: 100%;
}
"""
def compose(self):
yield Header()
yield Container(
Container(Sidebar(), id="main-content-sidebar"),
Container(Rendering(), id="main-content-rendering"),
id="main-content",
)
class MyApp(App):
async def on_mount(self):
self.install_screen(MyScreen(), "myscreen")
await self.push_screen("myscreen")
if __name__ == "__main__":
app = MyApp()
app.run()

View File

@@ -17,7 +17,6 @@ from textual.widgets import (
class WidgetDisableTestApp(App[None]): class WidgetDisableTestApp(App[None]):
CSS = """ CSS = """
Horizontal { Horizontal {
height: auto; height: auto;

View File

@@ -305,3 +305,7 @@ def test_remove_with_auto_height(snap_compare):
assert snap_compare( assert snap_compare(
SNAPSHOT_APPS_DIR / "remove_auto.py", press=["a", "a", "a", "d", "d"] SNAPSHOT_APPS_DIR / "remove_auto.py", press=["a", "a", "a", "d", "d"]
) )
def test_auto_table(snap_compare):
assert snap_compare(SNAPSHOT_APPS_DIR / "auto-table.py", terminal_size=(120, 40))