Skip to content

Commit 2413896

Browse files
committed
fix: align terminal redraw semantics and inline example fixtures
1 parent 0dbff6d commit 2413896

72 files changed

Lines changed: 2333 additions & 670 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

examples/alternate-screen/alternate-screen.py

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@
55
import time
66

77
from pyinkcli import Box, Text, render, useApp, useInput, useWindowSize
8-
from pyinkcli.hooks import useEffect, useRef, useState
8+
from pyinkcli.example_data import ALTERNATE_SCREEN_FOOD
9+
from pyinkcli.hooks import useEffect, useReducer, useRef
910

1011
HEAD = "🦄"
1112
BODY = "✨"
1213
FOOD = "🌈"
1314
EMPTY = " "
14-
TICK_MS = 0.15
15+
TICK_MS = 0.24
1516
BOARD_WIDTH = 20
1617
BOARD_HEIGHT = 15
1718
BORDER_H = "─" * (BOARD_WIDTH * 2)
@@ -27,18 +28,12 @@
2728
"right": (1, 0),
2829
}
2930

30-
OPPOSITES = {
31-
"up": "down",
32-
"down": "up",
33-
"left": "right",
34-
"right": "left",
35-
}
36-
3731
INITIAL_SNAKE = [
3832
{"x": 10, "y": 7},
3933
{"x": 9, "y": 7},
4034
{"x": 8, "y": 7},
4135
]
36+
FIXED_FOOD = dict(ALTERNATE_SCREEN_FOOD)
4237

4338

4439
def random_position(exclude):
@@ -54,19 +49,23 @@ def random_position(exclude):
5449
def initial_state():
5550
return {
5651
"snake": INITIAL_SNAKE,
57-
"food": random_position(INITIAL_SNAKE),
52+
"food": FIXED_FOOD,
5853
"score": 0,
5954
"game_over": False,
6055
"won": False,
6156
"frame": 0,
6257
}
6358

6459

65-
def tick_state(state, direction):
60+
def game_reducer(state, action):
61+
if action["type"] == "restart":
62+
return initial_state()
63+
6664
if state["game_over"]:
6765
return state
6866

6967
head = state["snake"][0]
68+
direction = action["direction"]
7069
offset_x, offset_y = OFFSETS[direction]
7170
new_head = {"x": head["x"] + offset_x, "y": head["y"] + offset_y}
7271

@@ -135,7 +134,7 @@ def build_board(snake, food):
135134
def alternate_screen_example():
136135
app = useApp()
137136
columns, _ = useWindowSize()
138-
game, set_game = useState(initial_state())
137+
game, dispatch = useReducer(game_reducer, None, lambda _arg: initial_state())
139138
direction = useRef("right")
140139

141140
def setup():
@@ -144,7 +143,7 @@ def setup():
144143
def run():
145144
while running:
146145
time.sleep(TICK_MS)
147-
set_game(lambda state: tick_state(state, direction.current))
146+
dispatch({"type": "tick", "direction": direction.current})
148147

149148
thread = threading.Thread(target=run, daemon=True)
150149
thread.start()
@@ -164,7 +163,7 @@ def on_input(char, key):
164163

165164
if game["game_over"] and char == "r":
166165
direction.current = "right"
167-
set_game(initial_state())
166+
dispatch({"type": "restart"})
168167
return
169168

170169
if game["game_over"]:
@@ -217,7 +216,6 @@ def on_input(char, key):
217216
),
218217
status,
219218
flexDirection="column",
220-
paddingY=1,
221219
)
222220

223221

examples/alternate-screen/index.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22

33
import runpy
44
from pathlib import Path
5+
import sys
6+
7+
ROOT = Path(__file__).resolve().parents[2]
8+
SRC = ROOT / "src"
9+
if str(SRC) in sys.path:
10+
sys.path.remove(str(SRC))
11+
sys.path.insert(0, str(SRC))
512

613
if __name__ == "__main__":
714
runpy.run_path(str(Path(__file__).with_name("alternate-screen.py")), run_name="__main__")

examples/aria/aria.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,10 @@ def on_input(char, _key):
1515

1616
return Box(
1717
Text(
18-
"Press spacebar to toggle the checkbox. This example is best experienced "
19-
"with a screen reader."
18+
"Press spacebar to toggle the checkbox. This example is best experienced with a\n"
19+
"screen reader."
2020
),
2121
Box(
22-
Text("checkbox:"),
2322
Box(
2423
Text("[x]" if checked else "[ ]"),
2524
aria_role="checkbox",

examples/aria/index.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22

33
import runpy
44
from pathlib import Path
5+
import sys
6+
7+
ROOT = Path(__file__).resolve().parents[2]
8+
SRC = ROOT / "src"
9+
if str(SRC) in sys.path:
10+
sys.path.remove(str(SRC))
11+
sys.path.insert(0, str(SRC))
512

613
if __name__ == "__main__":
714
runpy.run_path(str(Path(__file__).with_name("aria.py")), run_name="__main__")

examples/borders/borders.py

Lines changed: 34 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -4,64 +4,52 @@
44
Demonstrates different border styles available in pyinkcli.
55
"""
66

7-
from pyinkcli import Box, Text, render, useApp, useInput
7+
from pyinkcli import Box, Text, render
88

99

1010
def borders_example():
1111
"""Render boxes with different border styles."""
12-
app = useApp()
13-
14-
def on_input(input_char, key):
15-
if input_char == "q" or (key.ctrl and input_char == "c"):
16-
app.exit()
17-
18-
useInput(on_input)
19-
2012
return Box(
2113
Box(
2214
Box(
23-
Box(
24-
Text("single"),
25-
borderStyle="single",
26-
marginRight=2,
27-
),
28-
Box(
29-
Text("double"),
30-
borderStyle="double",
31-
marginRight=2,
32-
),
33-
Box(
34-
Text("round"),
35-
borderStyle="round",
36-
marginRight=2,
37-
),
38-
Box(
39-
Text("bold"),
40-
borderStyle="bold",
41-
),
15+
Text("single"),
16+
borderStyle="single",
17+
marginRight=2,
18+
),
19+
Box(
20+
Text("double"),
21+
borderStyle="double",
22+
marginRight=2,
23+
),
24+
Box(
25+
Text("round"),
26+
borderStyle="round",
27+
marginRight=2,
28+
),
29+
Box(
30+
Text("bold"),
31+
borderStyle="bold",
32+
),
33+
),
34+
Box(
35+
Box(
36+
Text("singleDouble"),
37+
borderStyle="singleDouble",
38+
marginRight=2,
39+
),
40+
Box(
41+
Text("doubleSingle"),
42+
borderStyle="doubleSingle",
43+
marginRight=2,
4244
),
4345
Box(
44-
Box(
45-
Text("singleDouble"),
46-
borderStyle="singleDouble",
47-
marginRight=2,
48-
),
49-
Box(
50-
Text("doubleSingle"),
51-
borderStyle="doubleSingle",
52-
marginRight=2,
53-
),
54-
Box(
55-
Text("classic"),
56-
borderStyle="classic",
57-
),
58-
marginTop=1,
46+
Text("classic"),
47+
borderStyle="classic",
5948
),
60-
flexDirection="column",
61-
padding=2,
49+
marginTop=1,
6250
),
63-
Text("\nPress 'q' to exit", dimColor=True),
6451
flexDirection="column",
52+
padding=2,
6553
)
6654

6755

examples/borders/index.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22

33
import runpy
44
from pathlib import Path
5+
import sys
6+
7+
ROOT = Path(__file__).resolve().parents[2]
8+
SRC = ROOT / "src"
9+
if str(SRC) in sys.path:
10+
sys.path.remove(str(SRC))
11+
sys.path.insert(0, str(SRC))
512

613
if __name__ == "__main__":
714
runpy.run_path(str(Path(__file__).with_name("borders.py")), run_name="__main__")

examples/box-backgrounds/box-backgrounds.py

Lines changed: 16 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,14 @@
11
"""box-backgrounds example for pyinkcli."""
22

3-
from pyinkcli import Box, Text, render, useApp, useInput
3+
from pyinkcli import Box, Text, render
44

55

66
def box_backgrounds_example():
7-
app = useApp()
8-
9-
def on_input(char, key):
10-
if char == "q" or (key.ctrl and char == "c"):
11-
app.exit()
12-
13-
useInput(on_input)
14-
157
return Box(
168
Text("Box Background Examples:", bold=True),
17-
Text("1. Standard red background (10x3):"),
9+
Box(Text("1. Standard red background (10x3):")),
1810
Box(Text("Hello"), backgroundColor="red", width=10, height=3, alignSelf="flex-start"),
19-
Text("2. Blue background with border (12x4):"),
11+
Box(Text("2. Blue background with border (12x4):")),
2012
Box(
2113
Text("Border"),
2214
backgroundColor="blue",
@@ -25,7 +17,7 @@ def on_input(char, key):
2517
height=4,
2618
alignSelf="flex-start",
2719
),
28-
Text("3. Green background with padding (14x4):"),
20+
Box(Text("3. Green background with padding (14x4):")),
2921
Box(
3022
Text("Padding"),
3123
backgroundColor="green",
@@ -34,7 +26,7 @@ def on_input(char, key):
3426
height=4,
3527
alignSelf="flex-start",
3628
),
37-
Text("4. Yellow background with center alignment (16x3):"),
29+
Box(Text("4. Yellow background with center alignment (16x3):")),
3830
Box(
3931
Text("Centered"),
4032
backgroundColor="yellow",
@@ -43,7 +35,7 @@ def on_input(char, key):
4335
justifyContent="center",
4436
alignSelf="flex-start",
4537
),
46-
Text("5. Magenta background, column layout (12x5):"),
38+
Box(Text("5. Magenta background, column layout (12x5):")),
4739
Box(
4840
Text("Line 1"),
4941
Text("Line 2"),
@@ -53,45 +45,47 @@ def on_input(char, key):
5345
height=5,
5446
alignSelf="flex-start",
5547
),
56-
Text("6. Hex color background #FF8800 (10x3):"),
48+
Box(Text("6. Hex color background #FF8800 (10x3):")),
5749
Box(
5850
Text("Hex"),
5951
backgroundColor="#FF8800",
6052
width=10,
6153
height=3,
6254
alignSelf="flex-start",
6355
),
64-
Text("7. RGB background rgb(0,255,0) (10x3):"),
56+
Box(Text("7. RGB background rgb(0,255,0) (10x3):")),
6557
Box(
6658
Text("RGB"),
6759
backgroundColor="rgb(0,255,0)",
6860
width=10,
6961
height=3,
7062
alignSelf="flex-start",
7163
),
72-
Text("8. Text inheritance test:"),
64+
Box(Text("8. Text inheritance test:")),
7365
Box(
7466
Text("Inherited "),
7567
Text("Override ", backgroundColor="red"),
7668
Text("Back to inherited"),
7769
backgroundColor="cyan",
7870
alignSelf="flex-start",
7971
),
80-
Text("9. Nested background inheritance:"),
72+
Box(Text("9. Nested background inheritance:")),
8173
Box(
82-
Text("Outer "),
74+
Text("Outer: "),
8375
Box(
84-
Text("Inner "),
76+
Text("Inner: "),
8577
Text("Deep", backgroundColor="red"),
8678
backgroundColor="yellow",
8779
),
8880
backgroundColor="blue",
8981
alignSelf="flex-start",
9082
),
91-
Text("Press 'q' to exit.", dimColor=True),
83+
Box(
84+
Text("Press Ctrl+C to exit"),
85+
marginTop=1,
86+
),
9287
flexDirection="column",
9388
gap=1,
94-
padding=1,
9589
)
9690

9791

examples/box-backgrounds/index.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22

33
import runpy
44
from pathlib import Path
5+
import sys
6+
7+
ROOT = Path(__file__).resolve().parents[2]
8+
SRC = ROOT / "src"
9+
if str(SRC) in sys.path:
10+
sys.path.remove(str(SRC))
11+
sys.path.insert(0, str(SRC))
512

613
if __name__ == "__main__":
714
runpy.run_path(str(Path(__file__).with_name("box-backgrounds.py")), run_name="__main__")

examples/chat/index.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22

33
import runpy
44
from pathlib import Path
5+
import sys
6+
7+
ROOT = Path(__file__).resolve().parents[2]
8+
SRC = ROOT / "src"
9+
if str(SRC) in sys.path:
10+
sys.path.remove(str(SRC))
11+
sys.path.insert(0, str(SRC))
512

613
if __name__ == "__main__":
714
runpy.run_path(str(Path(__file__).with_name("chat.py")), run_name="__main__")

0 commit comments

Comments
 (0)