Skip to content

Commit

Permalink
Replace existing layout algorithm with just Flex layout (#22)
Browse files Browse the repository at this point in the history
  • Loading branch information
JoshKarpel authored Jul 22, 2023
1 parent c57d4a8 commit d4f09de
Show file tree
Hide file tree
Showing 29 changed files with 1,577 additions and 1,177 deletions.
4 changes: 2 additions & 2 deletions codegen/colors.py
Original file line number Diff line number Diff line change
Expand Up @@ -304,8 +304,8 @@
for shade, hex in shades.items():
generated_lines.extend(
[
f'text_{color}_{shade} = Style(text=Text(style=CellStyle(foreground=Color.from_hex("{hex}"))))',
f'text_bg_{color}_{shade} = Style(text=Text(style=CellStyle(background=Color.from_hex("{hex}"))))',
f'text_{color}_{shade} = Style(typography=Typography(style=CellStyle(foreground=Color.from_hex("{hex}"))))',
f'text_bg_{color}_{shade} = Style(typography=Typography(style=CellStyle(background=Color.from_hex("{hex}"))))',
f'border_{color}_{shade} = Style(border=Border(style=CellStyle(foreground=Color.from_hex("{hex}"))))',
f'border_bg_{color}_{shade} = Style(border=Border(style=CellStyle(background=Color.from_hex("{hex}"))))',
f'margin_{color}_{shade} = Style(margin=Margin(color=Color.from_hex("{hex}")))',
Expand Down
4 changes: 2 additions & 2 deletions docs/app-flow.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ flowchart TB
subgraph Output
ph[Paint History]
dp[Diff Paint]
dp[Overlay & Diff Paint]
d[Apply Paint]
t[Terminal Output]
end
Expand All @@ -33,7 +33,7 @@ flowchart TB
p -- Paint --> dp
ph -- Previous Paint --> dp
dp -- Store Paint --> ph
dp -- Store Current Paint --> ph
dp -- Diffed Paint --> d
d -- VT Commands --> t
Expand Down
125 changes: 62 additions & 63 deletions examples/end_to_end.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,19 @@
from structlog import get_logger

from reprisal.app import app
from reprisal.components import Div, Paragraph, component
from reprisal.components import Div, Text, component
from reprisal.events import KeyPressed
from reprisal.hooks import Setter, use_effect, use_ref, use_state
from reprisal.keys import Key
from reprisal.styles import Border, BorderKind, Padding, Span, Style, ml_auto, mr_auto, mx_auto
from reprisal.styles import Border, BorderKind, Style
from reprisal.styles.styles import Flex, Padding
from reprisal.styles.utilities import (
border_amber_700,
border_bg_slate_700,
border_lime_700,
border_rose_500,
border_sky_700,
border_violet_500,
padding_amber_400,
text_bg_slate_300,
text_indigo_500,
border_teal_600,
text_rose_500,
text_teal_600,
)

Expand All @@ -28,32 +26,19 @@

@component
def toggle() -> Div:
border: BorderKind
set_border: Setter[BorderKind]
border_cycle_ref = use_ref(cycle(BorderKind))

def advance_border() -> BorderKind:
return next(border_cycle_ref.current)

border, set_border = use_state(advance_border) # type: ignore[arg-type]
border, set_border = use_state(advance_border)

margin_style: Style
set_margin_style: Setter[Style]
margin_cycle_ref = use_ref(cycle([mr_auto, mx_auto, ml_auto]))

def advance_margin() -> Style:
return next(margin_cycle_ref.current)

margin_style, set_margin_style = use_state(advance_margin) # type: ignore[arg-type]

border_color: Style
set_border_color: Setter[Style]
border_color_ref = use_ref(cycle([border_lime_700, border_amber_700, border_sky_700]))

def advance_border_color() -> Style:
return next(border_color_ref.current)

border_color, set_border_color = use_state(advance_border_color) # type: ignore[arg-type]
border_color, set_border_color = use_state(advance_border_color)

toggled, set_toggled = use_state(False)

Expand All @@ -65,51 +50,71 @@ def on_key(event: KeyPressed) -> None:
set_border(advance_border())
case Key.F2:
set_border_color(advance_border_color())
case Key.F3:
set_margin_style(advance_margin())

return Div(
children=[time(margin_style) if toggled else textpad(margin_style)],
style=border_color | Style(border=Border(kind=border)),
children=[
# TODO: why does putting this here break the layout? it's above the outer div...
# Paragraph(
# content="End-to-End Demo",
# style=Style(
# span=Span(width="auto"),
# border=Border(kind=BorderKind.LightRounded),
# ),
# ),
Div(
children=[
Text(
content="End-to-End Demo",
style=border_color
| Style(
border=Border(kind=border),
padding=Padding(top=1, bottom=1, left=1, right=1),
),
),
time() if toggled else textpad(),
],
style=Style(
display=Flex(direction="row"),
border=Border(kind=BorderKind.LightRounded),
),
),
],
style=Style(
display=Flex(
direction="column",
# TODO: without align_children="stretch", the children don't grow in width, even though they have text in them...
# maybe I'm applying auto width too late?
align_children="stretch",
),
),
on_key=on_key,
)


@component
def time(margin_style: Style) -> Div:
def time() -> Text:
now, set_now = use_state(datetime.now())

async def tick() -> None:
while True:
await asyncio.sleep(1)
await asyncio.sleep(0.01)
set_now(datetime.now())

use_effect(tick, deps=())

content = f"{now}"

return Div(
children=[
Paragraph(
content=content,
style=margin_style
| text_indigo_500
| text_bg_slate_300
| border_violet_500
| border_bg_slate_700
| padding_amber_400
| Style(
span=Span(width=len(content), height=1),
border=Border(kind=BorderKind.LightRounded),
padding=Padding(top=1, bottom=1, left=1, right=1),
),
)
]
return Text(
content=f"{now:%Y-%m-%d %H:%M:%S}",
style=text_rose_500
| border_teal_600
| Style(
border=Border(kind=BorderKind.LightRounded),
padding=Padding(top=1, bottom=1, left=1, right=1),
),
)


@component
def textpad(margin_style: Style) -> Div:
def textpad() -> Text:
buffer: list[str]
set_buffer: Setter[list[str]]
buffer, set_buffer = use_state([])
Expand All @@ -122,22 +127,16 @@ def on_key(event: KeyPressed) -> None:
s = [*buffer, event.key]
set_buffer(s)

content = "".join(buffer)
content = "".join(buffer) or "..."

return Div(
children=[
Paragraph(
content=content,
style=margin_style
| text_teal_600
| border_rose_500
| Style(
span=Span(width=len(content), height=1),
border=Border(kind=BorderKind.LightRounded),
padding=Padding(top=1, bottom=1, left=1, right=1),
),
)
],
return Text(
content=content,
style=text_teal_600
| border_rose_500
| Style(
border=Border(kind=BorderKind.LightRounded),
padding=Padding(top=1, bottom=1, left=1, right=1),
),
on_key=on_key,
)

Expand Down
76 changes: 0 additions & 76 deletions examples/inline.py

This file was deleted.

96 changes: 96 additions & 0 deletions examples/justify_and_align.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import shutil
from textwrap import dedent

from structlog import get_logger

from reprisal.components import Div, Text
from reprisal.layout import build_layout_tree
from reprisal.paint import debug_paint, paint_layout
from reprisal.styles import Border, BorderKind, Span, Style
from reprisal.styles.styles import Flex

logger = get_logger()

w, h = shutil.get_terminal_size()


def content(justify_children: str, align_children: str, n: int) -> Text:
return Text(
content=dedent(
f"""\
n={n}
j={justify_children}
a={align_children}
This is long enough text that it should wrap around,
but not necessarily at the comma.
"""
),
style=Style(
# TODO: width=auto doesn't make sense if weight=None, combine?
display=Flex(
weight=None,
),
span=Span(
width=20,
height="auto",
),
border=Border(kind=BorderKind.Light),
),
)


children = [
Div(
children=[content(justify_children, align_children, n=n) for n in range(3)],
style=Style(
display=Flex(
direction="row",
justify_children=justify_children, # type: ignore[arg-type]
align_children=align_children, # type: ignore[arg-type]
),
border=Border(kind=BorderKind.Heavy),
),
)
for justify_children in [
"start",
"center",
"end",
"space-between",
"space-around",
"space-evenly",
]
for align_children in [
"start",
"center",
"end",
"stretch",
]
]

root = Div(
children=children,
style=Style(
display=Flex(direction="column", align_children="stretch"),
span=Span(
width=w,
height=20 * len(children),
),
),
)
print(f"{len(children)=}")

t = build_layout_tree(root)
t.compute_layout()
# pprint(t.dict(exclude_defaults=True, include={"dims", "children"}))
p = paint_layout(t)
# pprint(t.dims.dict())
# for child in t.children:
# pprint(child.dims.dict())
print(t.dims)
for child in t.children:
print(child.dims)
_, _, margin_rect = t.dims.padding_border_margin_rects()
print(debug_paint(p, margin_rect))
Loading

0 comments on commit d4f09de

Please sign in to comment.