Repository navigation
Expand file tree
/
Copy pathtodo.py
More file actions
133 lines (108 loc) · 3.85 KB
/
Copy pathtodo.py
File metadata and controls
133 lines (108 loc) · 3.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
import pyui
def ITEM_ACTIVE(view):
return view
def ITEM_COMPLETE(view):
return view.color(255, 255, 255, 128)
class TodoItem:
def __init__(self, text, complete=False):
self.text = text
self.complete = complete
class TodoList(pyui.Observable):
def __init__(self):
self.items = []
@pyui.mutating
def add(self, title):
self.items.append(TodoItem(title))
@pyui.mutating
def toggle(self, checked, item):
item.complete = checked
@pyui.mutating
def toggle_all(self, checked):
for item in self.items:
item.complete = checked
@pyui.mutating
def delete(self, item):
self.items.remove(item)
@pyui.mutating
def clear_complete(self):
self.items = [item for item in self.items if not item.complete]
@property
def all_complete(self):
return len(self.items) > 0 and all(item.complete for item in self.items)
@property
def any_complete(self):
return any(item.complete for item in self.items)
@property
def remaining(self):
return len([item for item in self.items if not item.complete])
def filter(self, which):
for item in self.items:
if which == 0:
yield item
elif bool(which - 1) == item.complete:
yield item
class TodoMVC(pyui.View):
items = pyui.State(default=TodoList)
new_item = pyui.State(default="")
selected_filter = pyui.State(default=0)
@property
def selected(self):
yield from self.items.filter(self.selected_filter.value)
@property
def remaining_text(self):
remain = self.items.remaining
word = "item" if remain == 1 else "items"
return "{} {} left".format(remain, word)
async def add(self, title):
self.items.add(title)
self.new_item.value = ""
def content(self):
yield pyui.VStack(alignment=pyui.Alignment.LEADING)(
pyui.HStack()(
pyui.Toggle(self.items.all_complete, action=self.items.toggle_all),
pyui.TextField(
self.new_item,
"What needs to be done?",
action=self.add,
),
),
pyui.ScrollView()(
pyui.List(
self.selected,
builder=lambda item: (
pyui.HStack()(
pyui.Toggle(
item.complete,
label=item.text,
action=(self.items.toggle, item),
).modify(ITEM_COMPLETE if item.complete else ITEM_ACTIVE),
pyui.Spacer(),
pyui.Button(action=(self.items.delete, item), asset=None)(
pyui.Icon("trash-alt")
)
.font(size=12)
.padding(0),
)
),
),
).priority(pyui.Priority.HIGH),
pyui.HStack(
pyui.Text(self.remaining_text),
pyui.Button(action=self.items.clear_complete, asset=None)(
pyui.Text("Clear Completed").color(60, 150, 255)
)
.padding(5)
.disable(not self.items.any_complete),
pyui.Spacer(),
# TODO: would be nice to pass SegmentedButton an enum?
pyui.SegmentedButton(self.selected_filter)(
pyui.Text("All"),
pyui.Text("Active"),
pyui.Text("Completed"),
),
),
).padding(20)
if __name__ == "__main__":
app = pyui.Application("net.pyui.TodoMVC")
app.window("TodoMVC", TodoMVC(), height=320)
app.run()