mirror of
https://github.com/Textualize/textual.git
synced 2025-10-17 02:38:12 +03:00
ws
This commit is contained in:
31
examples/basic.py
Normal file
31
examples/basic.py
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
from textual.app import App
|
||||||
|
from textual.widgets import Placeholder
|
||||||
|
|
||||||
|
|
||||||
|
class BasicApp(App):
|
||||||
|
"""Demonstrates smooth animation. Press 'b' to see it in action."""
|
||||||
|
|
||||||
|
css = """
|
||||||
|
|
||||||
|
App > View {
|
||||||
|
layout: dock
|
||||||
|
}
|
||||||
|
|
||||||
|
#widget1 {
|
||||||
|
edge: top
|
||||||
|
}
|
||||||
|
|
||||||
|
#widget2 {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
async def on_mount(self) -> None:
|
||||||
|
"""Build layout here."""
|
||||||
|
|
||||||
|
await self.view.mount(widget1=Placeholder(), widget2=Placeholder())
|
||||||
|
|
||||||
|
|
||||||
|
SmoothApp.run(log="textual.log")
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
from rich.markdown import Markdown
|
from rich.markdown import Markdown
|
||||||
|
|
||||||
from textual import events
|
|
||||||
from textual.app import App
|
from textual.app import App
|
||||||
from textual.widgets import Header, Footer, Placeholder, ScrollView
|
from textual.widgets import Header, Footer, Placeholder, ScrollView
|
||||||
|
|
||||||
@@ -8,24 +7,38 @@ from textual.widgets import Header, Footer, Placeholder, ScrollView
|
|||||||
class MyApp(App):
|
class MyApp(App):
|
||||||
"""An example of a very simple Textual App"""
|
"""An example of a very simple Textual App"""
|
||||||
|
|
||||||
async def on_load(self, event: events.Load) -> None:
|
stylesheet = """
|
||||||
|
|
||||||
|
App > View {
|
||||||
|
layout: dock
|
||||||
|
}
|
||||||
|
|
||||||
|
#body {
|
||||||
|
padding: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
#sidebar {
|
||||||
|
edge left
|
||||||
|
size: 40
|
||||||
|
}
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
async def on_load(self) -> None:
|
||||||
"""Bind keys with the app loads (but before entering application mode)"""
|
"""Bind keys with the app loads (but before entering application mode)"""
|
||||||
await self.bind("b", "view.toggle('sidebar')", "Toggle sidebar")
|
await self.bind("b", "view.toggle('sidebar')", "Toggle sidebar")
|
||||||
await self.bind("q", "quit", "Quit")
|
await self.bind("q", "quit", "Quit")
|
||||||
|
|
||||||
async def on_mount(self, event: events.Mount) -> None:
|
async def on_mount(self) -> None:
|
||||||
"""Create and dock the widgets."""
|
"""Create and dock the widgets."""
|
||||||
|
|
||||||
# A scrollview to contain the markdown file
|
body = ScrollView()
|
||||||
body = ScrollView(gutter=1)
|
await self.view.mount(
|
||||||
|
Header(),
|
||||||
# Header / footer / dock
|
Footer(),
|
||||||
await self.view.dock(Header(), edge="top")
|
body=body,
|
||||||
await self.view.dock(Footer(), edge="bottom")
|
sidebar=Placeholder(),
|
||||||
await self.view.dock(Placeholder(), edge="left", size=30, name="sidebar")
|
)
|
||||||
|
|
||||||
# Dock the body in the remaining space
|
|
||||||
await self.view.dock(body, edge="right")
|
|
||||||
|
|
||||||
async def get_markdown(filename: str) -> None:
|
async def get_markdown(filename: str) -> None:
|
||||||
with open(filename, "rt") as fh:
|
with open(filename, "rt") as fh:
|
||||||
@@ -35,4 +48,4 @@ class MyApp(App):
|
|||||||
await self.call_later(get_markdown, "richreadme.md")
|
await self.call_later(get_markdown, "richreadme.md")
|
||||||
|
|
||||||
|
|
||||||
MyApp.run(title="Simple App", log="textual.log", css_file="theme.css")
|
MyApp.run(title="Simple App", log="textual.log")
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ class App(MessagePump):
|
|||||||
log_verbosity: int = 1,
|
log_verbosity: int = 1,
|
||||||
title: str = "Textual Application",
|
title: str = "Textual Application",
|
||||||
css_file: str | None = None,
|
css_file: str | None = None,
|
||||||
|
css: str | None = None,
|
||||||
):
|
):
|
||||||
"""The Textual Application base class
|
"""The Textual Application base class
|
||||||
|
|
||||||
@@ -112,6 +113,7 @@ class App(MessagePump):
|
|||||||
self.stylesheet = Stylesheet()
|
self.stylesheet = Stylesheet()
|
||||||
|
|
||||||
self.css_file = css_file
|
self.css_file = css_file
|
||||||
|
self.css = css
|
||||||
|
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
@@ -299,7 +301,8 @@ class App(MessagePump):
|
|||||||
try:
|
try:
|
||||||
if self.css_file is not None:
|
if self.css_file is not None:
|
||||||
self.stylesheet.read(self.css_file)
|
self.stylesheet.read(self.css_file)
|
||||||
print(self.stylesheet.css)
|
if self.css is not None:
|
||||||
|
self.stylesheet.parse(self.css)
|
||||||
except Exception:
|
except Exception:
|
||||||
self.panic()
|
self.panic()
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ if TYPE_CHECKING:
|
|||||||
from .styles import Styles
|
from .styles import Styles
|
||||||
|
|
||||||
|
|
||||||
class _BoxProperty:
|
class BoxProperty:
|
||||||
|
|
||||||
DEFAULT = ("", Style())
|
DEFAULT = ("", Style())
|
||||||
|
|
||||||
@@ -67,7 +67,7 @@ class Edges(NamedTuple):
|
|||||||
yield "left", left
|
yield "left", left
|
||||||
|
|
||||||
|
|
||||||
class _BorderProperty:
|
class BorderProperty:
|
||||||
def __set_name__(self, owner: Styles, name: str) -> None:
|
def __set_name__(self, owner: Styles, name: str) -> None:
|
||||||
self._properties = (
|
self._properties = (
|
||||||
f"{name}_top",
|
f"{name}_top",
|
||||||
@@ -129,14 +129,21 @@ class _BorderProperty:
|
|||||||
raise StyleValueError("expected 1, 2, or 4 values")
|
raise StyleValueError("expected 1, 2, or 4 values")
|
||||||
|
|
||||||
|
|
||||||
class _StyleProperty:
|
class StyleProperty:
|
||||||
|
|
||||||
|
DEFAULT_STYLE = Style()
|
||||||
|
|
||||||
def __set_name__(self, owner: Styles, name: str) -> None:
|
def __set_name__(self, owner: Styles, name: str) -> None:
|
||||||
self._internal_name = f"_{name}"
|
self._internal_name = f"_{name}"
|
||||||
|
|
||||||
def __get__(self, obj: Styles, objtype: type[Styles] | None = None) -> Style:
|
def __get__(self, obj: Styles, objtype: type[Styles] | None = None) -> Style:
|
||||||
return getattr(obj, self._internal_name)
|
return getattr(obj, self._internal_name) or self.DEFAULT_STYLE
|
||||||
|
|
||||||
|
def __set__(self, obj: Styles, style: Style | str | None) -> Style | str | None:
|
||||||
|
if style is None:
|
||||||
|
setattr(obj, self._internal_name, None)
|
||||||
|
return None
|
||||||
|
|
||||||
def __set__(self, obj: Styles, style: Style | str) -> Style:
|
|
||||||
if isinstance(style, str):
|
if isinstance(style, str):
|
||||||
_style = Style.parse(style)
|
_style = Style.parse(style)
|
||||||
else:
|
else:
|
||||||
@@ -145,7 +152,7 @@ class _StyleProperty:
|
|||||||
return _style
|
return _style
|
||||||
|
|
||||||
|
|
||||||
class _SpacingProperty:
|
class SpacingProperty:
|
||||||
def __set_name__(self, owner: Styles, name: str) -> None:
|
def __set_name__(self, owner: Styles, name: str) -> None:
|
||||||
self._internal_name = f"_{name}"
|
self._internal_name = f"_{name}"
|
||||||
|
|
||||||
@@ -158,7 +165,7 @@ class _SpacingProperty:
|
|||||||
return spacing
|
return spacing
|
||||||
|
|
||||||
|
|
||||||
class _DocksProperty:
|
class DocksProperty:
|
||||||
def __get__(
|
def __get__(
|
||||||
self, obj: Styles, objtype: type[Styles] | None = None
|
self, obj: Styles, objtype: type[Styles] | None = None
|
||||||
) -> tuple[str, ...]:
|
) -> tuple[str, ...]:
|
||||||
@@ -173,7 +180,7 @@ class _DocksProperty:
|
|||||||
return _docks
|
return _docks
|
||||||
|
|
||||||
|
|
||||||
class _DockGroupProperty:
|
class DockGroupProperty:
|
||||||
def __get__(self, obj: Styles, objtype: type[Styles] | None = None) -> str:
|
def __get__(self, obj: Styles, objtype: type[Styles] | None = None) -> str:
|
||||||
return obj._dock_group or ""
|
return obj._dock_group or ""
|
||||||
|
|
||||||
@@ -182,7 +189,7 @@ class _DockGroupProperty:
|
|||||||
return spacing
|
return spacing
|
||||||
|
|
||||||
|
|
||||||
class _OffsetProperty:
|
class OffsetProperty:
|
||||||
def __set_name__(self, owner: Styles, name: str) -> None:
|
def __set_name__(self, owner: Styles, name: str) -> None:
|
||||||
self._internal_name = f"_{name}"
|
self._internal_name = f"_{name}"
|
||||||
|
|
||||||
@@ -195,7 +202,7 @@ class _OffsetProperty:
|
|||||||
return offset
|
return offset
|
||||||
|
|
||||||
|
|
||||||
class _DockEdgeProperty:
|
class DockEdgeProperty:
|
||||||
def __get__(self, obj: Styles, objtype: type[Styles] | None = None) -> str:
|
def __get__(self, obj: Styles, objtype: type[Styles] | None = None) -> str:
|
||||||
return obj._dock_edge or ""
|
return obj._dock_edge or ""
|
||||||
|
|
||||||
@@ -204,3 +211,37 @@ class _DockEdgeProperty:
|
|||||||
raise ValueError(f"dock edge must be one of {friendly_list(VALID_EDGE)}")
|
raise ValueError(f"dock edge must be one of {friendly_list(VALID_EDGE)}")
|
||||||
obj._dock_edge = edge
|
obj._dock_edge = edge
|
||||||
return edge
|
return edge
|
||||||
|
|
||||||
|
|
||||||
|
class IntegerProperty:
|
||||||
|
def __set_name__(self, owner: Styles, name: str) -> None:
|
||||||
|
self._internal_name = f"_{name}"
|
||||||
|
|
||||||
|
def __get__(self, obj: Styles, objtype: type[Styles] | None = None) -> int:
|
||||||
|
return getattr(obj, self._internal_name, 0)
|
||||||
|
|
||||||
|
def __set__(self, obj: Styles, value: int | None) -> int | None:
|
||||||
|
setattr(obj, self._internal_name, value)
|
||||||
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
class StringProperty:
|
||||||
|
def __init__(self, valid_values: set[str], default: str) -> None:
|
||||||
|
self._valid_values = valid_values
|
||||||
|
self._default = default
|
||||||
|
|
||||||
|
def __set_name__(self, owner: Styles, name: str) -> None:
|
||||||
|
self._name = name
|
||||||
|
self._internal_name = f"_{name}"
|
||||||
|
|
||||||
|
def __get__(self, obj: Styles, objtype: type[Styles] | None = None) -> str:
|
||||||
|
return getattr(obj, self._internal_name, self._default)
|
||||||
|
|
||||||
|
def __set__(self, obj: Styles, value: str | None = None) -> str | None:
|
||||||
|
if value is not None:
|
||||||
|
if value not in self._valid_values:
|
||||||
|
raise StyleValueError(
|
||||||
|
f"{self._name} must be one of {friendly_list(self._valid_values)}"
|
||||||
|
)
|
||||||
|
setattr(obj, self._internal_name, value)
|
||||||
|
return value
|
||||||
|
|||||||
@@ -16,14 +16,16 @@ from .constants import (
|
|||||||
)
|
)
|
||||||
from ..geometry import NULL_OFFSET, Offset, Spacing
|
from ..geometry import NULL_OFFSET, Offset, Spacing
|
||||||
from ._style_properties import (
|
from ._style_properties import (
|
||||||
_BorderProperty,
|
BorderProperty,
|
||||||
_BoxProperty,
|
BoxProperty,
|
||||||
_DockEdgeProperty,
|
DockEdgeProperty,
|
||||||
_DocksProperty,
|
DocksProperty,
|
||||||
_DockGroupProperty,
|
DockGroupProperty,
|
||||||
_OffsetProperty,
|
IntegerProperty,
|
||||||
_SpacingProperty,
|
OffsetProperty,
|
||||||
_StyleProperty,
|
SpacingProperty,
|
||||||
|
StringProperty,
|
||||||
|
StyleProperty,
|
||||||
)
|
)
|
||||||
from .types import Display, Visibility
|
from .types import Display, Visibility
|
||||||
|
|
||||||
@@ -33,10 +35,10 @@ class Styles:
|
|||||||
|
|
||||||
_display: Display | None = None
|
_display: Display | None = None
|
||||||
_visibility: Visibility | None = None
|
_visibility: Visibility | None = None
|
||||||
|
_layout: str | None = None
|
||||||
|
|
||||||
_text: Style = Style()
|
_text: Style | None = None
|
||||||
|
|
||||||
_layout: str = ""
|
|
||||||
_padding: Spacing | None = None
|
_padding: Spacing | None = None
|
||||||
_margin: Spacing | None = None
|
_margin: Spacing | None = None
|
||||||
_offset: Offset | None = None
|
_offset: Offset | None = None
|
||||||
@@ -51,71 +53,45 @@ class Styles:
|
|||||||
_outline_bottom: tuple[str, Style] | None = None
|
_outline_bottom: tuple[str, Style] | None = None
|
||||||
_outline_left: tuple[str, Style] | None = None
|
_outline_left: tuple[str, Style] | None = None
|
||||||
|
|
||||||
|
_size: int | None = None
|
||||||
|
_fraction: int | None = None
|
||||||
|
_min_size: int | None = None
|
||||||
|
|
||||||
_dock_group: str | None = None
|
_dock_group: str | None = None
|
||||||
_dock_edge: str | None = None
|
_dock_edge: str | None = None
|
||||||
_docks: tuple[str, ...] | None = None
|
_docks: tuple[str, ...] | None = None
|
||||||
|
|
||||||
important: set[str] = field(default_factory=set)
|
important: set[str] = field(default_factory=set)
|
||||||
|
|
||||||
@property
|
display = StringProperty(VALID_DISPLAY, "block")
|
||||||
def display(self) -> Display:
|
visibility = StringProperty(VALID_VISIBILITY, "visible")
|
||||||
return self._display or "block"
|
layout = StringProperty(VALID_LAYOUT, "dock")
|
||||||
|
|
||||||
@display.setter
|
text = StyleProperty()
|
||||||
def display(self, display: Display) -> None:
|
|
||||||
if display not in VALID_DISPLAY:
|
|
||||||
raise StyleValueError(
|
|
||||||
f"display must be one of {friendly_list(VALID_DISPLAY)}"
|
|
||||||
)
|
|
||||||
self._display = display
|
|
||||||
|
|
||||||
@property
|
padding = SpacingProperty()
|
||||||
def visibility(self) -> Visibility:
|
margin = SpacingProperty()
|
||||||
return self._visibility or "visible"
|
offset = OffsetProperty()
|
||||||
|
|
||||||
@visibility.setter
|
border = BorderProperty()
|
||||||
def visibility(self, visibility: Visibility) -> None:
|
border_top = BoxProperty()
|
||||||
if visibility not in VALID_VISIBILITY:
|
border_right = BoxProperty()
|
||||||
raise StyleValueError(
|
border_bottom = BoxProperty()
|
||||||
f"visibility must be one of {friendly_list(VALID_VISIBILITY)}"
|
border_left = BoxProperty()
|
||||||
)
|
|
||||||
self._visibility = visibility
|
|
||||||
|
|
||||||
text = _StyleProperty()
|
outline = BorderProperty()
|
||||||
|
outline_top = BoxProperty()
|
||||||
|
outline_right = BoxProperty()
|
||||||
|
outline_bottom = BoxProperty()
|
||||||
|
outline_left = BoxProperty()
|
||||||
|
|
||||||
@property
|
size = IntegerProperty()
|
||||||
def layout(self) -> str:
|
fraction = IntegerProperty()
|
||||||
return self._layout
|
min_size = IntegerProperty()
|
||||||
|
|
||||||
@layout.setter
|
dock_group = DockGroupProperty()
|
||||||
def layout(self, layout: str) -> None:
|
docks = DocksProperty()
|
||||||
if layout not in VALID_LAYOUT:
|
dock_edge = DockEdgeProperty()
|
||||||
raise StyleValueError(
|
|
||||||
f"layout must be one of {friendly_list(VALID_LAYOUT)}"
|
|
||||||
)
|
|
||||||
self._layout = layout
|
|
||||||
|
|
||||||
offset = _OffsetProperty()
|
|
||||||
|
|
||||||
padding = _SpacingProperty()
|
|
||||||
margin = _SpacingProperty()
|
|
||||||
|
|
||||||
border = _BorderProperty()
|
|
||||||
border_top = _BoxProperty()
|
|
||||||
border_right = _BoxProperty()
|
|
||||||
border_bottom = _BoxProperty()
|
|
||||||
border_left = _BoxProperty()
|
|
||||||
|
|
||||||
outline = _BorderProperty()
|
|
||||||
outline_top = _BoxProperty()
|
|
||||||
outline_right = _BoxProperty()
|
|
||||||
outline_bottom = _BoxProperty()
|
|
||||||
outline_left = _BoxProperty()
|
|
||||||
|
|
||||||
dock_group = _DockGroupProperty()
|
|
||||||
docks = _DocksProperty()
|
|
||||||
|
|
||||||
dock_edge = _DockEdgeProperty()
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def has_border(self) -> bool:
|
def has_border(self) -> bool:
|
||||||
@@ -238,7 +214,6 @@ if __name__ == "__main__":
|
|||||||
styles.docks = "foo bar"
|
styles.docks = "foo bar"
|
||||||
styles.text = "italic blue"
|
styles.text = "italic blue"
|
||||||
styles.dock_group = "bar"
|
styles.dock_group = "bar"
|
||||||
styles.dock_edge = "sdfsdf"
|
|
||||||
|
|
||||||
from rich import inspect, print
|
from rich import inspect, print
|
||||||
|
|
||||||
|
|||||||
@@ -41,10 +41,6 @@ class Dock:
|
|||||||
|
|
||||||
|
|
||||||
class DockLayout(Layout):
|
class DockLayout(Layout):
|
||||||
def __init__(self, docks: list[Dock] = None) -> None:
|
|
||||||
self.docks: list[Dock] = docks or []
|
|
||||||
super().__init__()
|
|
||||||
|
|
||||||
def get_widgets(self) -> Iterable[Widget]:
|
def get_widgets(self) -> Iterable[Widget]:
|
||||||
for dock in self.docks:
|
for dock in self.docks:
|
||||||
yield from dock.widgets
|
yield from dock.widgets
|
||||||
|
|||||||
@@ -41,7 +41,9 @@ class View(Widget):
|
|||||||
|
|
||||||
layout_factory: ClassVar[Callable[[], Layout]]
|
layout_factory: ClassVar[Callable[[], Layout]]
|
||||||
|
|
||||||
def __init__(self, layout: Layout = None, name: str | None = None) -> None:
|
def __init__(
|
||||||
|
self, layout: Layout = None, name: str | None = None, id: str | None = None
|
||||||
|
) -> None:
|
||||||
self._layout: Layout = layout or self.layout_factory()
|
self._layout: Layout = layout or self.layout_factory()
|
||||||
|
|
||||||
self.mouse_over: Widget | None = None
|
self.mouse_over: Widget | None = None
|
||||||
@@ -55,7 +57,7 @@ class View(Widget):
|
|||||||
[],
|
[],
|
||||||
)
|
)
|
||||||
|
|
||||||
super().__init__(name=name)
|
super().__init__(name=name, id=id)
|
||||||
|
|
||||||
def __init_subclass__(
|
def __init_subclass__(
|
||||||
cls, layout: Callable[[], Layout] | None = None, **kwargs
|
cls, layout: Callable[[], Layout] | None = None, **kwargs
|
||||||
@@ -144,7 +146,7 @@ class View(Widget):
|
|||||||
for name, widget in name_widgets:
|
for name, widget in name_widgets:
|
||||||
if name is not None:
|
if name is not None:
|
||||||
widget.name = name
|
widget.name = name
|
||||||
self.add_child(widget)
|
self._add_child(widget)
|
||||||
|
|
||||||
self.refresh()
|
self.refresh()
|
||||||
|
|
||||||
|
|||||||
@@ -21,16 +21,21 @@ class DockView(View):
|
|||||||
async def dock(
|
async def dock(
|
||||||
self,
|
self,
|
||||||
*widgets: Widget,
|
*widgets: Widget,
|
||||||
|
name: str | None = None,
|
||||||
|
id: str | None = None,
|
||||||
edge: DockEdge = "top",
|
edge: DockEdge = "top",
|
||||||
z: int = 0,
|
z: int = 0,
|
||||||
size: int | None | DoNotSet = do_not_set,
|
size: int | None | DoNotSet = do_not_set,
|
||||||
name: str | None = None,
|
|
||||||
) -> None:
|
) -> None:
|
||||||
|
|
||||||
dock = Dock(edge, widgets, z)
|
dock = Dock(edge, widgets, z)
|
||||||
assert isinstance(self._layout, DockLayout)
|
assert isinstance(self._layout, DockLayout)
|
||||||
self._layout.docks.append(dock)
|
self._layout.docks.append(dock)
|
||||||
for widget in widgets:
|
for widget in widgets:
|
||||||
|
if id is not None:
|
||||||
|
widget._id = id
|
||||||
|
if name is not None:
|
||||||
|
widget.name = name
|
||||||
if size is not do_not_set:
|
if size is not do_not_set:
|
||||||
widget.layout_size = cast(Optional[int], size)
|
widget.layout_size = cast(Optional[int], size)
|
||||||
if name is None:
|
if name is None:
|
||||||
@@ -42,17 +47,18 @@ class DockView(View):
|
|||||||
async def dock_grid(
|
async def dock_grid(
|
||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
|
name: str | None = None,
|
||||||
|
id: str | None = None,
|
||||||
edge: DockEdge = "top",
|
edge: DockEdge = "top",
|
||||||
z: int = 0,
|
z: int = 0,
|
||||||
size: int | None | DoNotSet = do_not_set,
|
size: int | None | DoNotSet = do_not_set,
|
||||||
name: str | None = None,
|
|
||||||
gap: tuple[int, int] | int | None = None,
|
gap: tuple[int, int] | int | None = None,
|
||||||
gutter: tuple[int, int] | int | None = None,
|
gutter: tuple[int, int] | int | None = None,
|
||||||
align: tuple[GridAlign, GridAlign] | None = None,
|
align: tuple[GridAlign, GridAlign] | None = None,
|
||||||
) -> GridLayout:
|
) -> GridLayout:
|
||||||
|
|
||||||
grid = GridLayout(gap=gap, gutter=gutter, align=align)
|
grid = GridLayout(gap=gap, gutter=gutter, align=align)
|
||||||
view = View(layout=grid, name=name)
|
view = View(layout=grid, id=id, name=name)
|
||||||
dock = Dock(edge, (view,), z)
|
dock = Dock(edge, (view,), z)
|
||||||
assert isinstance(self._layout, DockLayout)
|
assert isinstance(self._layout, DockLayout)
|
||||||
self._layout.docks.append(dock)
|
self._layout.docks.append(dock)
|
||||||
|
|||||||
@@ -85,7 +85,6 @@ class Widget(MessagePump):
|
|||||||
|
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
id: str | None = None
|
|
||||||
visible: Reactive[bool] = Reactive(True, layout=True)
|
visible: Reactive[bool] = Reactive(True, layout=True)
|
||||||
layout_size: Reactive[int | None] = Reactive(None, layout=True)
|
layout_size: Reactive[int | None] = Reactive(None, layout=True)
|
||||||
layout_fraction: Reactive[int] = Reactive(1, layout=True)
|
layout_fraction: Reactive[int] = Reactive(1, layout=True)
|
||||||
@@ -124,7 +123,7 @@ class Widget(MessagePump):
|
|||||||
renderable = self.render_styled()
|
renderable = self.render_styled()
|
||||||
return renderable
|
return renderable
|
||||||
|
|
||||||
def add_child(self, widget: Widget) -> Widget:
|
def _add_child(self, widget: Widget) -> Widget:
|
||||||
"""Add a child widget.
|
"""Add a child widget.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@@ -134,12 +133,21 @@ class Widget(MessagePump):
|
|||||||
self.children._append(widget)
|
self.children._append(widget)
|
||||||
return widget
|
return widget
|
||||||
|
|
||||||
def get_child(self, name: str | None = None) -> Widget:
|
def get_child(self, name: str | None = None, id: str | None = None) -> Widget:
|
||||||
|
if name is not None:
|
||||||
for widget in self.children:
|
for widget in self.children:
|
||||||
if widget.name == name:
|
if widget.name == name:
|
||||||
return widget
|
return widget
|
||||||
|
if id is not None:
|
||||||
|
for widget in self.children:
|
||||||
|
if widget.id == id:
|
||||||
|
return widget
|
||||||
raise errors.MissingWidget(f"Widget named {name!r} was not found in {self}")
|
raise errors.MissingWidget(f"Widget named {name!r} was not found in {self}")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def id(self) -> str | None:
|
||||||
|
return self._id
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def class_names(self) -> frozenset[str]:
|
def class_names(self) -> frozenset[str]:
|
||||||
return frozenset(self._class_names)
|
return frozenset(self._class_names)
|
||||||
@@ -188,6 +196,7 @@ class Widget(MessagePump):
|
|||||||
if self.padding is not None:
|
if self.padding is not None:
|
||||||
renderable = Padding(renderable, self.padding)
|
renderable = Padding(renderable, self.padding)
|
||||||
if self.border not in ("", "none"):
|
if self.border not in ("", "none"):
|
||||||
|
1 / 0
|
||||||
_border_style = self.console.get_style(self.border_style)
|
_border_style = self.console.get_style(self.border_style)
|
||||||
renderable = Border(
|
renderable = Border(
|
||||||
renderable,
|
renderable,
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from logging import getLogger
|
from logging import getLogger
|
||||||
|
|
||||||
|
|||||||
@@ -35,15 +35,13 @@ class ScrollView(View):
|
|||||||
super().__init__(name=name, layout=layout)
|
super().__init__(name=name, layout=layout)
|
||||||
|
|
||||||
self.fluid = fluid
|
self.fluid = fluid
|
||||||
self.vscroll = self.add_child(ScrollBar(vertical=True))
|
self.vscroll = ScrollBar(vertical=True)
|
||||||
self.hscroll = self.add_child(ScrollBar(vertical=False))
|
self.hscroll = ScrollBar(vertical=False)
|
||||||
self.window = self.add_child(
|
self.window = WindowView(
|
||||||
WindowView(
|
|
||||||
"" if contents is None else contents,
|
"" if contents is None else contents,
|
||||||
auto_width=auto_width,
|
auto_width=auto_width,
|
||||||
gutter=gutter,
|
gutter=gutter,
|
||||||
)
|
)
|
||||||
)
|
|
||||||
|
|
||||||
layout.add_column("main")
|
layout.add_column("main")
|
||||||
layout.add_column("vscroll", size=1)
|
layout.add_column("vscroll", size=1)
|
||||||
|
|||||||
Reference in New Issue
Block a user