feat: big title
This commit is contained in:
@@ -19,9 +19,11 @@ from uframe.ir import (
|
||||
Heading, Text, Label, Divider, Link, ListNode, ListItem,
|
||||
Gauge, Sparkline, Status, Table,
|
||||
Form, Field, Password, Radio, Checkbox, FormButton,
|
||||
BigTitle,
|
||||
HeadingLevel, DividerStyle, ListStyle, Align, BorderWeight,
|
||||
)
|
||||
from uframe.themes import ThemeDef, THEME_DEFAULT
|
||||
from uframe.fonts import render_big_text, get_text_width, FONT_HEIGHTS
|
||||
|
||||
|
||||
def _align_text(text: str, width: int, align: Align) -> str:
|
||||
@@ -220,6 +222,38 @@ def paint(node: IRNode, grid: CharGrid, theme: ThemeDef | None = None) -> None:
|
||||
grid.put(x, y, char, style=CellStyle(fg=color))
|
||||
grid.put_text(x + 2, y, node.label)
|
||||
|
||||
elif isinstance(node, BigTitle):
|
||||
style = CellStyle(fg=node.style.fg or th.palette.accent, bold=True)
|
||||
|
||||
# Determine which font fits
|
||||
font = node.font
|
||||
tw = get_text_width(node.text, font)
|
||||
if tw > w:
|
||||
# Try fallback cascade
|
||||
for fallback in ["pixel", "thin"]:
|
||||
if get_text_width(node.text, fallback) <= w:
|
||||
font = fallback
|
||||
tw = get_text_width(node.text, fallback)
|
||||
break
|
||||
else:
|
||||
# Final fallback: styled single line
|
||||
styled = f"═══ {node.text.upper()} ═══"
|
||||
grid.put_text(x, y, styled[:w], style=style)
|
||||
return
|
||||
|
||||
lines = render_big_text(node.text, font)
|
||||
|
||||
# Center if align is set
|
||||
offset = 0
|
||||
if node.style.align == Align.CENTER:
|
||||
offset = max(0, (w - tw) // 2)
|
||||
elif node.style.align == Align.RIGHT:
|
||||
offset = max(0, w - tw)
|
||||
|
||||
for row_i, line in enumerate(lines):
|
||||
if y + row_i < grid.height:
|
||||
grid.put_text(x + offset, y + row_i, line, style=style)
|
||||
|
||||
elif isinstance(node, Table):
|
||||
_paint_table(node, grid, x, y, w)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user