mirror of
https://github.com/Textualize/textual.git
synced 2025-10-17 02:38:12 +03:00
newline
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
from textual import events
|
||||
from textual.app import App
|
||||
from textual.reactive import Reactive
|
||||
from textual.views import DockView
|
||||
from textual.widgets import Footer, Placeholder
|
||||
|
||||
|
||||
@@ -9,33 +8,29 @@ class SmoothApp(App):
|
||||
"""Demonstrates smooth animation"""
|
||||
|
||||
async def on_load(self, event: events.Load) -> None:
|
||||
await self.bind("q,ctrl+c", "quit")
|
||||
await self.bind("x", "bang")
|
||||
await self.bind("b", "toggle_sidebar")
|
||||
"""Bing keys here."""
|
||||
await self.bind("b", "toggle_sidebar", "Toggle sidebar")
|
||||
await self.bind("q", "quit", "Quit")
|
||||
|
||||
show_bar: Reactive[bool] = Reactive(False)
|
||||
|
||||
async def watch_show_bar(self, show_bar: bool) -> None:
|
||||
"""Called when show_bar changes."""
|
||||
self.animator.animate(self.bar, "layout_offset_x", 0 if show_bar else -40)
|
||||
|
||||
async def action_toggle_sidebar(self) -> None:
|
||||
"""Called when user hits b key."""
|
||||
self.show_bar = not self.show_bar
|
||||
|
||||
async def on_startup(self, event: events.Startup) -> None:
|
||||
|
||||
view = await self.push_view(DockView())
|
||||
|
||||
"""Build layout here."""
|
||||
footer = Footer()
|
||||
self.bar = Placeholder(name="left")
|
||||
self.bar.layout_offset_x = -40
|
||||
|
||||
footer.add_key("b", "Toggle sidebar")
|
||||
footer.add_key("q", "Quit")
|
||||
|
||||
await view.dock(footer, edge="bottom")
|
||||
await view.dock(self.bar, edge="left", size=40, z=1)
|
||||
|
||||
await view.dock(Placeholder(), Placeholder(), edge="top")
|
||||
await self.view.dock(footer, edge="bottom")
|
||||
await self.view.dock(self.bar, edge="left", size=40, z=1)
|
||||
await self.view.dock(Placeholder(), Placeholder(), edge="top")
|
||||
|
||||
|
||||
SmoothApp.run()
|
||||
|
||||
@@ -108,22 +108,23 @@ class CalculatorApp(App):
|
||||
async def on_startup(self, event: events.Startup) -> None:
|
||||
"""Sent when the app has gone full screen."""
|
||||
|
||||
# Create the layout which defines where our widgets will go
|
||||
layout = GridLayout(gap=(2, 1), gutter=1, align=("center", "center"))
|
||||
await self.push_view(View(layout=layout))
|
||||
# Create a grid layout
|
||||
grid = await self.view.dock_grid(
|
||||
gap=(2, 1), gutter=1, align=("center", "center")
|
||||
)
|
||||
|
||||
# Create rows / columns / areas
|
||||
layout.add_column("col", max_size=30, repeat=4)
|
||||
layout.add_row("numbers", max_size=15)
|
||||
layout.add_row("row", max_size=15, repeat=5)
|
||||
layout.add_areas(
|
||||
grid.add_column("col", max_size=30, repeat=4)
|
||||
grid.add_row("numbers", max_size=15)
|
||||
grid.add_row("row", max_size=15, repeat=5)
|
||||
grid.add_areas(
|
||||
clear="col1,row1",
|
||||
numbers="col1-start|col4-end,numbers",
|
||||
zero="col1-start|col2-end,row5",
|
||||
)
|
||||
# Place out widgets in to the layout
|
||||
layout.place(clear=self.c)
|
||||
layout.place(
|
||||
grid.place(clear=self.c)
|
||||
grid.place(
|
||||
*self.buttons.values(), clear=self.ac, numbers=self.numbers, zero=self.zero
|
||||
)
|
||||
|
||||
|
||||
@@ -11,25 +11,24 @@ class GridTest(App):
|
||||
|
||||
async def on_startup(self, event: events.Startup) -> None:
|
||||
|
||||
layout = GridLayout()
|
||||
await self.push_view(View(layout=layout))
|
||||
grid = await self.view.dock_grid()
|
||||
|
||||
layout.add_column(fraction=1, name="left", min_size=20)
|
||||
layout.add_column(size=30, name="center")
|
||||
layout.add_column(fraction=1, name="right")
|
||||
grid.add_column(fraction=1, name="left", min_size=20)
|
||||
grid.add_column(size=30, name="center")
|
||||
grid.add_column(fraction=1, name="right")
|
||||
|
||||
layout.add_row(fraction=1, name="top", min_size=2)
|
||||
layout.add_row(fraction=2, name="middle")
|
||||
layout.add_row(fraction=1, name="bottom")
|
||||
grid.add_row(fraction=1, name="top", min_size=2)
|
||||
grid.add_row(fraction=2, name="middle")
|
||||
grid.add_row(fraction=1, name="bottom")
|
||||
|
||||
layout.add_areas(
|
||||
grid.add_areas(
|
||||
area1="left,top",
|
||||
area2="center,middle",
|
||||
area3="left-start|right-end,bottom",
|
||||
area4="right,top-start|middle-end",
|
||||
)
|
||||
|
||||
layout.place(
|
||||
grid.place(
|
||||
area1=Placeholder(name="area1"),
|
||||
area2=Placeholder(name="area2"),
|
||||
area3=Placeholder(name="area3"),
|
||||
|
||||
@@ -11,16 +11,15 @@ class GridTest(App):
|
||||
|
||||
async def on_startup(self, event: events.Startup) -> None:
|
||||
|
||||
layout = GridLayout()
|
||||
await self.push_view(View(layout=layout))
|
||||
grid = await self.view.dock_grid()
|
||||
|
||||
layout.add_column("col", fraction=1, max_size=20)
|
||||
layout.add_row("row", fraction=1, max_size=10)
|
||||
layout.set_repeat(True, True)
|
||||
layout.add_areas(center="col-2-start|col-4-end,row-2-start|row-3-end")
|
||||
layout.set_align("stretch", "center")
|
||||
grid.add_column("col", fraction=1, max_size=20)
|
||||
grid.add_row("row", fraction=1, max_size=10)
|
||||
grid.set_repeat(True, True)
|
||||
grid.add_areas(center="col-2-start|col-4-end,row-2-start|row-3-end")
|
||||
grid.set_align("stretch", "center")
|
||||
|
||||
layout.place(*(Placeholder() for _ in range(20)), center=Placeholder())
|
||||
grid.place(*(Placeholder() for _ in range(20)), center=Placeholder())
|
||||
|
||||
|
||||
GridTest.run(title="Grid Test")
|
||||
|
||||
@@ -2,7 +2,6 @@ from rich.markdown import Markdown
|
||||
|
||||
from textual import events
|
||||
from textual.app import App
|
||||
from textual.views import DockView
|
||||
from textual.widgets import Header, Footer, Placeholder, ScrollView
|
||||
|
||||
|
||||
@@ -10,25 +9,17 @@ class MyApp(App):
|
||||
"""An example of a very simple Textual App"""
|
||||
|
||||
async def on_load(self, event: events.Load) -> None:
|
||||
await self.bind("q,ctrl+c", "quit", "Quit")
|
||||
await self.bind("b", "view.toggle('sidebar')", "Toggle sidebar")
|
||||
await self.bind("q", "quit", "Quit")
|
||||
|
||||
async def on_startup(self, event: events.Startup) -> None:
|
||||
|
||||
view = await self.push_view(DockView())
|
||||
|
||||
footer = Footer()
|
||||
header = Header()
|
||||
body = ScrollView()
|
||||
sidebar = Placeholder()
|
||||
|
||||
footer.add_key("b", "Toggle sidebar")
|
||||
footer.add_key("q", "Quit")
|
||||
|
||||
await view.dock(header, edge="top")
|
||||
await view.dock(footer, edge="bottom")
|
||||
await view.dock(sidebar, edge="left", size=30, name="sidebar")
|
||||
await view.dock(body, edge="right")
|
||||
await self.view.dock(Header(), edge="top")
|
||||
await self.view.dock(Footer(), edge="bottom")
|
||||
await self.view.dock(Placeholder(), edge="left", size=30, name="sidebar")
|
||||
await self.view.dock(body, edge="right")
|
||||
|
||||
async def get_markdown(filename: str) -> None:
|
||||
with open(filename, "rt") as fh:
|
||||
|
||||
32
poetry.lock
generated
32
poetry.lock
generated
@@ -369,11 +369,11 @@ pyparsing = ">=2.0.2"
|
||||
|
||||
[[package]]
|
||||
name = "pathspec"
|
||||
version = "0.8.1"
|
||||
version = "0.9.0"
|
||||
description = "Utility library for gitignore style pattern matching of file paths."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7"
|
||||
|
||||
[[package]]
|
||||
name = "platformdirs"
|
||||
@@ -547,17 +547,24 @@ version = "10.6.0"
|
||||
description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6,<4.0"
|
||||
python-versions = "^3.6"
|
||||
develop = false
|
||||
|
||||
[package.dependencies]
|
||||
colorama = ">=0.4.0,<0.5.0"
|
||||
commonmark = ">=0.9.0,<0.10.0"
|
||||
pygments = ">=2.6.0,<3.0.0"
|
||||
typing-extensions = {version = ">=3.7.4,<4.0.0", markers = "python_version < \"3.8\""}
|
||||
colorama = "^0.4.0"
|
||||
commonmark = "^0.9.0"
|
||||
pygments = "^2.6.0"
|
||||
typing-extensions = {version = "^3.7.4", markers = "python_version < \"3.8\""}
|
||||
|
||||
[package.extras]
|
||||
jupyter = ["ipywidgets (>=7.5.1,<8.0.0)"]
|
||||
|
||||
[package.source]
|
||||
type = "git"
|
||||
url = "git@github.com:willmcgugan/rich"
|
||||
reference = "link-id"
|
||||
resolved_reference = "c4c00a2d0441519ced7ab2dead931341d9345eda"
|
||||
|
||||
[[package]]
|
||||
name = "six"
|
||||
version = "1.16.0"
|
||||
@@ -636,7 +643,7 @@ testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytes
|
||||
[metadata]
|
||||
lock-version = "1.1"
|
||||
python-versions = "^3.7"
|
||||
content-hash = "b78b6843dbfa68dd86e0ec81c9f1980f57eb85c13d1df9b497c34762e8805699"
|
||||
content-hash = "89e70da124ff666d5f911585eb2032d523499bcfe3c0efad9b2f5367cc64183b"
|
||||
|
||||
[metadata.files]
|
||||
appdirs = [
|
||||
@@ -865,8 +872,8 @@ packaging = [
|
||||
{file = "packaging-21.0.tar.gz", hash = "sha256:7dc96269f53a4ccec5c0670940a4281106dd0bb343f47b7471f779df49c2fbe7"},
|
||||
]
|
||||
pathspec = [
|
||||
{file = "pathspec-0.8.1-py2.py3-none-any.whl", hash = "sha256:aa0cb481c4041bf52ffa7b0d8fa6cd3e88a2ca4879c533c9153882ee2556790d"},
|
||||
{file = "pathspec-0.8.1.tar.gz", hash = "sha256:86379d6b86d75816baba717e64b1a3a3469deb93bb76d613c9ce79edc5cb68fd"},
|
||||
{file = "pathspec-0.9.0-py2.py3-none-any.whl", hash = "sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a"},
|
||||
{file = "pathspec-0.9.0.tar.gz", hash = "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"},
|
||||
]
|
||||
platformdirs = [
|
||||
{file = "platformdirs-2.0.2-py2.py3-none-any.whl", hash = "sha256:0b9547541f599d3d242078ae60b927b3e453f0ad52f58b4d4bc3be86aed3ec41"},
|
||||
@@ -990,10 +997,7 @@ regex = [
|
||||
{file = "regex-2021.7.6-cp39-cp39-win_amd64.whl", hash = "sha256:4c9c3155fe74269f61e27617529b7f09552fbb12e44b1189cebbdb24294e6e1c"},
|
||||
{file = "regex-2021.7.6.tar.gz", hash = "sha256:8394e266005f2d8c6f0bc6780001f7afa3ef81a7a2111fa35058ded6fce79e4d"},
|
||||
]
|
||||
rich = [
|
||||
{file = "rich-10.6.0-py3-none-any.whl", hash = "sha256:d3f72827cd5df13b2ef7f1a97f81ec65548d4fdeb92cef653234f227580bbb2a"},
|
||||
{file = "rich-10.6.0.tar.gz", hash = "sha256:128261b3e2419a4ef9c97066ccc2abbfb49fa7c5e89c3fe4056d00aa5e9c1e65"},
|
||||
]
|
||||
rich = []
|
||||
six = [
|
||||
{file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
|
||||
{file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
|
||||
|
||||
@@ -21,8 +21,8 @@ classifiers = [
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.7"
|
||||
rich = "^10.6.0"
|
||||
#rich = {git = "git@github.com:willmcgugan/rich", rev = "height-fixes"}
|
||||
#rich = "^10.6.0"
|
||||
rich = {git = "git@github.com:willmcgugan/rich", rev = "link-id"}
|
||||
typing-extensions = { version = "^3.10.0", python = "<3.8" }
|
||||
|
||||
[tool.poetry.dev-dependencies]
|
||||
|
||||
@@ -11,13 +11,11 @@ import rich.repr
|
||||
from rich.screen import Screen
|
||||
from rich import get_console
|
||||
from rich.console import Console, RenderableType
|
||||
from rich.style import Style
|
||||
from rich.traceback import Traceback
|
||||
|
||||
from . import events
|
||||
from . import actions
|
||||
from ._animator import Animator
|
||||
from ._profile import timer
|
||||
from .binding import Bindings, NoBinding
|
||||
from .geometry import Point, Region
|
||||
from . import log
|
||||
@@ -92,7 +90,7 @@ class App(MessagePump):
|
||||
self.driver_class = driver_class or LinuxDriver
|
||||
self._title = title
|
||||
self._layout = DockLayout()
|
||||
self._view_stack: list[View] = []
|
||||
self._view_stack: list[DockView] = []
|
||||
self.children: set[MessagePump] = set()
|
||||
|
||||
self.focused: Widget | None = None
|
||||
@@ -111,7 +109,7 @@ class App(MessagePump):
|
||||
|
||||
self.log_file = open(log, "wt") if log else None
|
||||
|
||||
self.bindings.bind("ctrl+c", "quit")
|
||||
self.bindings.bind("ctrl+c", "quit", show=False)
|
||||
|
||||
super().__init__()
|
||||
|
||||
@@ -130,7 +128,7 @@ class App(MessagePump):
|
||||
return self._animator
|
||||
|
||||
@property
|
||||
def view(self) -> View:
|
||||
def view(self) -> DockView:
|
||||
return self._view_stack[-1]
|
||||
|
||||
def log(self, *args: Any, verbosity: int = 0) -> None:
|
||||
@@ -143,9 +141,16 @@ class App(MessagePump):
|
||||
pass
|
||||
|
||||
async def bind(
|
||||
self, keys: str, action: str, description: str = "", show: bool = False
|
||||
self,
|
||||
keys: str,
|
||||
action: str,
|
||||
description: str = "",
|
||||
show: bool = True,
|
||||
key_display: str | None = None,
|
||||
) -> None:
|
||||
self.bindings.bind(keys, action, description, show=show)
|
||||
self.bindings.bind(
|
||||
keys, action, description, show=show, key_display=key_display
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def run(
|
||||
@@ -246,7 +251,7 @@ class App(MessagePump):
|
||||
log(f"driver={self.driver_class}")
|
||||
|
||||
await self.dispatch_message(events.Load(sender=self))
|
||||
await self.push_view(View())
|
||||
await self.push_view(DockView())
|
||||
|
||||
try:
|
||||
driver.start_application_mode()
|
||||
@@ -345,14 +350,18 @@ class App(MessagePump):
|
||||
def get_widget_at(self, x: int, y: int) -> tuple[Widget, Region]:
|
||||
return self.view.get_widget_at(x, y)
|
||||
|
||||
async def on_event(self, event: events.Event) -> None:
|
||||
if isinstance(event, events.Key):
|
||||
async def press(self, key: str) -> bool:
|
||||
try:
|
||||
binding = self.bindings.get_key(event.key)
|
||||
binding = self.bindings.get_key(key)
|
||||
except NoBinding:
|
||||
pass
|
||||
return False
|
||||
else:
|
||||
await self.action(binding.action)
|
||||
return True
|
||||
|
||||
async def on_event(self, event: events.Event) -> None:
|
||||
if isinstance(event, events.Key):
|
||||
if await self.press(event.key):
|
||||
return
|
||||
await super().on_event(event)
|
||||
|
||||
@@ -425,6 +434,9 @@ class App(MessagePump):
|
||||
async def on_resize(self, event: events.Resize) -> None:
|
||||
await self.view.post_message(event)
|
||||
|
||||
async def action_press(self, key: str) -> None:
|
||||
await self.press(key)
|
||||
|
||||
async def action_quit(self) -> None:
|
||||
await self.shutdown()
|
||||
|
||||
@@ -467,9 +479,9 @@ if __name__ == "__main__":
|
||||
"""Just a test app."""
|
||||
|
||||
async def on_load(self, event: events.Load) -> None:
|
||||
await self.bind("q,ctrl+c", "quit")
|
||||
await self.bind("x", "bang")
|
||||
await self.bind("b", "toggle_sidebar")
|
||||
await self.bind("q,ctrl+c", "quit", "Exit app")
|
||||
await self.bind("x", "bang", "Test error handling")
|
||||
await self.bind("b", "toggle_sidebar", "Toggle sidebar")
|
||||
|
||||
show_bar: Reactive[bool] = Reactive(False)
|
||||
|
||||
@@ -486,8 +498,6 @@ if __name__ == "__main__":
|
||||
header = Header()
|
||||
footer = Footer()
|
||||
self.bar = Placeholder(name="left")
|
||||
footer.add_key("b", "Toggle sidebar")
|
||||
footer.add_key("q", "Quit")
|
||||
|
||||
await view.dock(header, edge="top")
|
||||
await view.dock(footer, edge="bottom")
|
||||
|
||||
@@ -12,6 +12,7 @@ class Binding:
|
||||
action: str
|
||||
description: str
|
||||
show: bool = False
|
||||
key_display: str | None = None
|
||||
|
||||
|
||||
class Bindings:
|
||||
@@ -20,16 +21,24 @@ class Bindings:
|
||||
def __init__(self) -> None:
|
||||
self.keys: dict[str, Binding] = {}
|
||||
|
||||
@property
|
||||
def shown_keys(self) -> list[Binding]:
|
||||
keys = [binding for binding in self.keys.values() if binding.show]
|
||||
return keys
|
||||
|
||||
def bind(
|
||||
self, keys: str, action: str, description: str = "", show: bool = False
|
||||
self,
|
||||
keys: str,
|
||||
action: str,
|
||||
description: str = "",
|
||||
show: bool = True,
|
||||
key_display: str | None = None,
|
||||
) -> None:
|
||||
all_keys = [key.strip() for key in keys.split(",")]
|
||||
for key in all_keys:
|
||||
self.keys[key] = Binding(key, action, description, show=show)
|
||||
self.keys[key] = Binding(
|
||||
key, action, description, show=show, key_display=key_display
|
||||
)
|
||||
|
||||
def get_key(self, key: str) -> Binding:
|
||||
try:
|
||||
|
||||
@@ -8,6 +8,7 @@ import rich.repr
|
||||
from rich.style import Style
|
||||
|
||||
from . import events
|
||||
from . import log
|
||||
from .layout import Layout, NoWidget
|
||||
from .layouts.dock import DockLayout
|
||||
from .geometry import Dimensions, Point, Region
|
||||
@@ -30,6 +31,8 @@ class View(Widget):
|
||||
self.size = Dimensions(0, 0)
|
||||
self.widgets: set[Widget] = set()
|
||||
self.named_widgets: dict[str, Widget] = {}
|
||||
self._mouse_style: Style = Style()
|
||||
self._mouse_widget: Widget | None = None
|
||||
super().__init__(name)
|
||||
|
||||
background: Reactive[str] = Reactive("")
|
||||
@@ -148,6 +151,7 @@ class View(Widget):
|
||||
await self.refresh_layout()
|
||||
|
||||
async def _on_mouse_move(self, event: events.MouseMove) -> None:
|
||||
|
||||
try:
|
||||
if self.app.mouse_captured:
|
||||
widget = self.app.mouse_captured
|
||||
@@ -157,8 +161,13 @@ class View(Widget):
|
||||
except NoWidget:
|
||||
await self.app.set_mouse_over(None)
|
||||
else:
|
||||
await self.app.set_mouse_over(widget)
|
||||
if event.style is not self._mouse_style and self._mouse_widget:
|
||||
await self.app.broker_event("leave", event, self._mouse_widget)
|
||||
await self.app.broker_event("enter", event, widget)
|
||||
|
||||
self._mouse_style = event.style
|
||||
self._mouse_widget = widget
|
||||
await self.app.set_mouse_over(widget)
|
||||
await widget.forward_event(
|
||||
events.MouseMove(
|
||||
self,
|
||||
|
||||
@@ -2,6 +2,7 @@ from __future__ import annotations
|
||||
from typing import cast, Optional
|
||||
|
||||
from ..layouts.dock import DockLayout, Dock, DockEdge
|
||||
from ..layouts.grid import GridLayout, GridAlign
|
||||
from ..view import View
|
||||
from ..widget import Widget
|
||||
|
||||
@@ -23,7 +24,7 @@ class DockView(View):
|
||||
edge: DockEdge = "top",
|
||||
z: int = 0,
|
||||
size: int | None | DoNotSet = do_not_set,
|
||||
name: str | None = None
|
||||
name: str | None = None,
|
||||
) -> None:
|
||||
|
||||
dock = Dock(edge, widgets, z)
|
||||
@@ -38,3 +39,29 @@ class DockView(View):
|
||||
else:
|
||||
await self.mount(**{name: widget})
|
||||
await self.refresh_layout()
|
||||
|
||||
async def dock_grid(
|
||||
self,
|
||||
*,
|
||||
edge: DockEdge = "top",
|
||||
z: int = 0,
|
||||
size: int | None | DoNotSet = do_not_set,
|
||||
name: str | None = None,
|
||||
gap: tuple[int, int] | int | None = None,
|
||||
gutter: tuple[int, int] | int | None = None,
|
||||
align: tuple[GridAlign, GridAlign] | None = None,
|
||||
) -> GridLayout:
|
||||
|
||||
grid = GridLayout(gap=gap, gutter=gutter, align=align)
|
||||
view = View(layout=grid)
|
||||
dock = Dock(edge, (view,), z)
|
||||
assert isinstance(self.layout, DockLayout)
|
||||
self.layout.docks.append(dock)
|
||||
if size is not do_not_set:
|
||||
view.layout_size = cast(Optional[int], size)
|
||||
if not self.is_mounted(view):
|
||||
if name is None:
|
||||
await self.mount(view)
|
||||
else:
|
||||
await self.mount(**{name: view})
|
||||
return grid
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
from rich.console import RenderableType
|
||||
from rich.style import Style
|
||||
from rich.text import Text
|
||||
import rich.repr
|
||||
|
||||
from .. import events
|
||||
from ..widget import Widget
|
||||
|
||||
|
||||
@@ -20,7 +20,6 @@ class Footer(Widget):
|
||||
self.keys.append((key, label))
|
||||
|
||||
def render(self) -> RenderableType:
|
||||
|
||||
text = Text(
|
||||
style="white on dark_green",
|
||||
no_wrap=True,
|
||||
@@ -28,7 +27,19 @@ class Footer(Widget):
|
||||
justify="left",
|
||||
end="",
|
||||
)
|
||||
for key, label in self.keys:
|
||||
text.append(f" {key.upper()} ", style="default on default")
|
||||
text.append(f" {label} ")
|
||||
for binding in self.app.bindings.shown_keys:
|
||||
key_display = (
|
||||
binding.key.upper()
|
||||
if binding.key_display is None
|
||||
else binding.key_display
|
||||
)
|
||||
key_text = Text.assemble(
|
||||
(f" {key_display} ", "default on default"), f" {binding.description} "
|
||||
)
|
||||
key_text.stylize(Style(meta={"@click": f"app.press('{binding.key}')"}))
|
||||
text.append_text(key_text)
|
||||
# text.append(f" {key_display} ", style="default on default")
|
||||
# text.append(f" {binding.description} ")
|
||||
|
||||
# text.stylize(Style(meta={"@enter": "app.bell()"}))
|
||||
return text
|
||||
|
||||
Reference in New Issue
Block a user