Skip to content

Commit 87ef8b4

Browse files
committed
ListBox helper added
1 parent ce011b6 commit 87ef8b4

File tree

6 files changed

+165
-0
lines changed

6 files changed

+165
-0
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
## New features
44

55
* text itself can be `InSteps`
6+
* `ListBox` helper added
67

78

89
# 0.4

docs/guide/list.md

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# List
2+
3+
Lists are not build-in in Nelsie. You can create lists manually, or you can create
4+
a helper class `ListBox` for creating lists.
5+
6+
`ListBox` takes a box as a first parameter and creates list in this box.
7+
`ListBox` behaves as a normal vertical box but creates a bullet for each child.
8+
9+
## Unordered list
10+
11+
```nelsie
12+
from nelsie.helpers.list import ListBox
13+
14+
@deck.slide()
15+
def list_demo(slide):
16+
slide.set_style("default", TextStyle(size=80))
17+
lst = ListBox(slide)
18+
lst.text("First item")
19+
lst.text("Second item")
20+
lst.text("Third item")
21+
```
22+
23+
## Ordered list
24+
25+
You can change type of by setting a second argument `list_type` to following values:
26+
27+
- `"unordered"` (default) - Unordered list
28+
- `"1"` - Ordered list, 1., 2., 3. ...
29+
- `"a"` - Ordered list, a., b., c. ...
30+
- `"A"` - Ordered list, A., B., C. ...
31+
32+
```nelsie
33+
from nelsie.helpers.list import ListBox
34+
35+
@deck.slide()
36+
def list_demo(slide):
37+
slide.set_style("default", TextStyle(size=80))
38+
lst = ListBox(slide, "1")
39+
lst.text("First item")
40+
lst.text("Second item")
41+
lst.text("Third item")
42+
```
43+
44+
45+
```nelsie
46+
from nelsie.helpers.list import ListBox
47+
48+
@deck.slide()
49+
def list_demo(slide):
50+
slide.set_style("default", TextStyle(size=80))
51+
lst = ListBox(slide, "a")
52+
lst.text("First item")
53+
lst.text("Second item")
54+
lst.text("Third item")
55+
```
56+
57+
58+
## Sublists
59+
60+
A sublist can be created by calling `.list()` method on an existing `ListBox`.
61+
It returns an instance of `ListBox`.
62+
63+
```nelsie
64+
from nelsie.helpers.list import ListBox
65+
66+
@deck.slide()
67+
def list_demo(slide):
68+
slide.set_style("default", TextStyle(size=80))
69+
70+
lst = ListBox(slide)
71+
lst.text("First item")
72+
lst.text("Second item")
73+
74+
lst2 = lst.list()
75+
lst2.text("Hello")
76+
lst2.text("World!")
77+
```

mkdocs.yml

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ nav:
2929
- guide/resources.md
3030
- guide/box.md
3131
- guide/colors.md
32+
- guide/list.md
3233

3334
theme:
3435
name: material

python/nelsie/helpers/list.py

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
from typing import Callable
2+
3+
from ..box import Box, BoxBuilder
4+
5+
6+
DEFAULT_BULLETS = ("•", "⁃", "‣")
7+
8+
9+
class ListBox(BoxBuilder):
10+
def __init__(
11+
self, parent_box: Box, list_type: str | Callable = "unordered", style="default", indent_size=1.1, counters=None
12+
):
13+
self.main_box = parent_box.box(align_items="start")
14+
if isinstance(style, str):
15+
style = parent_box.get_style(style)
16+
self.style = style
17+
self.indent_size = indent_size * style.size
18+
self.list_type = list_type
19+
if counters is None:
20+
self.counters = [0]
21+
else:
22+
self.counters = counters[:] + [0]
23+
24+
@property
25+
def level(self):
26+
return len(self.counters) - 1
27+
28+
def get_box(self):
29+
return self.main_box
30+
31+
def create_item_boxes(self, box_args) -> (Box, Box):
32+
item_box = self.main_box.box(row=True, align_items="start")
33+
box1 = item_box.box(row=True, width=self.indent_size, justify_content="start")
34+
box2 = item_box.box(**box_args)
35+
return box1, box2
36+
37+
def box(self, **box_args) -> Box:
38+
self.counters[-1] += 1
39+
box1, box2 = self.create_item_boxes(box_args)
40+
if isinstance(self.list_type, Callable):
41+
self.list_type(box1)
42+
elif self.list_type == "unordered":
43+
box1.text(DEFAULT_BULLETS[self.level % len(DEFAULT_BULLETS)], style=self.style)
44+
elif self.list_type == "1":
45+
box1.text(f"{self.counters[-1]}.", style=self.style)
46+
elif self.list_type == "a":
47+
box1.text(f"{chr(ord('a') - 1 + self.counters[-1])}.", style=self.style)
48+
elif self.list_type == "A":
49+
box1.text(f"{chr(ord('A') - 1 + self.counters[-1])}.", style=self.style)
50+
return box2
51+
52+
def list(self, list_type="unordered", **box_args):
53+
box1, box2 = self.create_item_boxes(box_args)
54+
return ListBox(box2, list_type=list_type, counters=self.counters)

tests/checks/list/0-1.png

18.5 KB
Loading

tests/test_list.py

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
from nelsie import TextStyle
2+
from nelsie.helpers.list import ListBox
3+
from testutils import check
4+
5+
6+
@check()
7+
def test_list(deck):
8+
slide = deck.new_slide(width=200, height=300)
9+
slide.set_style("default", TextStyle(size=12))
10+
lst = ListBox(slide)
11+
lst.text("One")
12+
lst.text("Two1\nTwo2\nTwo3")
13+
lst.text("Long item three")
14+
lst2 = lst.list()
15+
lst2.text("A")
16+
lst2.text("BB")
17+
lst2.text("CCC")
18+
lst2 = lst.list(list_type="1")
19+
lst2.text("A")
20+
lst2.text("BB")
21+
lst2.text("CCC")
22+
lst2 = lst.list(list_type="a")
23+
lst2.text("A")
24+
lst2.text("BB")
25+
lst2.text("CCC")
26+
lst2 = lst.list(list_type="A")
27+
lst2.text("A")
28+
lst2.text("BB")
29+
lst2.text("CCC")
30+
lst3 = lst2.list()
31+
lst3.text("Hello!")
32+
lst.text("Fourth item")

0 commit comments

Comments
 (0)