mirror of https://github.com/Textualize/rich.git
130 lines
4.0 KiB
Python
130 lines
4.0 KiB
Python
from datetime import datetime
|
|
from rich.console import Console
|
|
from rich.layout import Layout
|
|
from rich.panel import Panel
|
|
from rich.progress import Progress, SpinnerColumn, BarColumn, TextColumn
|
|
from rich.syntax import Syntax
|
|
from rich.table import Table
|
|
|
|
from rich.__main__ import make_test_card
|
|
|
|
console = Console()
|
|
|
|
|
|
def make_layout() -> Layout:
|
|
layout = Layout(name="root")
|
|
|
|
layout.split(name="header", size=3)
|
|
body = layout.split(name="main", ratio=1, direction="horizontal")
|
|
layout.split(size=7, name="footer")
|
|
|
|
side = body.split(name="side")
|
|
body.split(name="body", ratio=2)
|
|
|
|
side.split(name="box1")
|
|
side.split(name="box2")
|
|
return layout
|
|
|
|
|
|
class Header:
|
|
def __rich__(self) -> Panel:
|
|
grid = Table.grid(expand=True)
|
|
grid.add_column(justify="center", ratio=1)
|
|
grid.add_column(justify="right")
|
|
grid.add_row(
|
|
"[b]Rich[/b] Layout application",
|
|
datetime.now().ctime().replace(":", "[blink]:[/]"),
|
|
)
|
|
return Panel(grid, style="white on blue")
|
|
|
|
|
|
code = """\
|
|
def ratio_resolve(total: int, edges: List[Edge]) -> List[int]:
|
|
sizes = [(edge.size or None) for edge in edges]
|
|
|
|
# While any edges haven't been calculated
|
|
while any(size is None for size in sizes):
|
|
# Get flexible edges and index to map these back on to sizes list
|
|
flexible_edges = [
|
|
(index, edge)
|
|
for index, (size, edge) in enumerate(zip(sizes, edges))
|
|
if size is None
|
|
]
|
|
# Remaining space in total
|
|
remaining = total - sum(size or 0 for size in sizes)
|
|
if remaining <= 0:
|
|
# No room for flexible edges
|
|
sizes[:] = [(size or 0) for size in sizes]
|
|
break
|
|
# Calculate number of characters in a ratio portion
|
|
portion = remaining / sum((edge.ratio or 1) for _, edge in flexible_edges)
|
|
|
|
# If any edges will be less than their minimum, replace size with the minimum
|
|
for index, edge in flexible_edges:
|
|
if portion * edge.ratio <= edge.minimum_size:
|
|
sizes[index] = edge.minimum_size
|
|
break
|
|
else:
|
|
# Distribute flexible space and compensate for rounding error
|
|
# Since edge sizes can only be integers we need to add the remainder
|
|
# to the following line
|
|
_modf = modf
|
|
remainder = 0.0
|
|
for index, edge in flexible_edges:
|
|
remainder, size = _modf(portion * edge.ratio + remainder)
|
|
sizes[index] = int(size)
|
|
break
|
|
# Sizes now contains integers only
|
|
return cast(List[int], sizes)
|
|
"""
|
|
syntax = Syntax(code, "python", line_numbers=True)
|
|
|
|
|
|
layout = make_layout()
|
|
layout["header"].update(Header())
|
|
layout["body"].update(make_test_card())
|
|
|
|
|
|
layout["box2"].update(Panel(syntax, border_style="green"))
|
|
|
|
layout["box1"].update(Panel(layout.tree, border_style="red"))
|
|
|
|
|
|
job_progress = Progress(
|
|
"{task.description}",
|
|
SpinnerColumn(),
|
|
BarColumn(),
|
|
TextColumn("[progress.percentage]{task.percentage:>3.0f}%"),
|
|
)
|
|
job1 = job_progress.add_task("[green]Cooking")
|
|
job2 = job_progress.add_task("[magenta]Baking", total=200)
|
|
job3 = job_progress.add_task("[cyan]Mixing", total=400)
|
|
|
|
total = sum(task.total for task in job_progress.tasks)
|
|
overall_progress = Progress()
|
|
overall_task = overall_progress.add_task("All Jobs", total=int(total))
|
|
|
|
progress_table = Table.grid(expand=True)
|
|
progress_table.add_row(
|
|
Panel(
|
|
overall_progress, title="Overall Progress", border_style="green", padding=(2, 2)
|
|
),
|
|
Panel(job_progress, title="[b]Jobs", border_style="red", padding=(1, 2)),
|
|
)
|
|
|
|
layout["footer"].update(progress_table)
|
|
|
|
|
|
from rich.live import Live
|
|
from time import sleep
|
|
|
|
with Live(layout, refresh_per_second=10, screen=True):
|
|
while not overall_progress.finished:
|
|
sleep(0.1)
|
|
for job in job_progress.tasks:
|
|
if not job.finished:
|
|
job_progress.advance(job.id)
|
|
|
|
completed = sum(task.completed for task in job_progress.tasks)
|
|
overall_progress.update(overall_task, completed=completed)
|