/
selectlist.py
148 lines (122 loc) · 4.13 KB
/
selectlist.py
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
import collections
from kaa import document
from kaa.ui.dialog import dialogmode
from kaa.keyboard import *
from kaa.command import commandid, norec, norerun
SelectItem = collections.namedtuple(
'SelectItem', ['style', 'activestyle', 'text', 'value'])
selectlist_keys = {
down: 'selectitemlist.next',
(ctrl, 'n'): 'selectitemlist.next',
(ctrl, 'f'): 'selectitemlist.next',
tab: 'selectitemlist.next',
up: 'selectitemlist.prev',
(ctrl, 'p'): 'selectitemlist.prev',
(ctrl, 'b'): 'selectitemlist.prev',
(shift, tab): 'selectitemlist.prev',
}
class SelectItemList(dialogmode.DialogMode):
USE_UNDO = False
NO_WRAPINDENT = False
CAPTION_STYLE = 'caption'
items = ()
cursel = None
filterfunc = None
caption = None
SEP = ' '
@classmethod
def build(cls):
doc = document.Document()
mode = cls()
doc.setmode(mode)
return doc
def is_cursor_visible(self):
return 0 # hide cursor
def init_keybind(self):
super().init_keybind()
self.keybind.add_keybind(selectlist_keys)
def on_str(self, wnd, s, overwrite=False):
pass
def calc_height(self, wnd):
height = wnd.screen.get_total_height()
height = min(height, wnd.mainframe.height // 2)
return height
def update_doc(self, items):
self.items = list(collections.OrderedDict((i, 1)
for i in items).keys())
self.cursel = None
self.document.marks.clear()
self.document.delete(0, self.document.endpos())
with dialogmode.FormBuilder(self.document) as f:
if self.caption:
f.append_text(self.CAPTION_STYLE, self.caption + ':\n')
for n, item in enumerate(self.items):
f.append_text(item.style, item.text, mark_pair=item)
if n != (len(self.items) - 1):
f.append_text('default', self.SEP)
def _update_item_style(
self, wnd, item, activate, middle=None, bottom=None):
if item not in self.document.marks:
return
if activate:
style = item.activestyle
else:
style = item.style
f, t = self.document.marks[item]
self.document.setstyles(f, t, self.get_styleid(style))
if activate:
wnd.screen.apply_updates()
top = not middle and not bottom
wnd.screen.locate(f, top=top, middle=middle, bottom=bottom)
wnd.update_window()
def update_sel(self, wnd, newsel, middle=None, bottom=None):
if self.cursel is not None:
self._update_item_style(wnd, self.cursel, False)
if newsel is not None:
self._update_item_style(wnd, newsel, True,
middle=middle, bottom=bottom)
self.cursel = newsel
@commandid('selectitemlist.next')
@norec
@norerun
def sel_next(self, wnd):
if not self.items:
newsel = None
elif self.cursel is None:
newsel = self.items[0]
else:
try:
idx = self.items.index(self.cursel)
except ValueError:
newsel = self.items[0]
else:
if idx < len(self.items) - 1:
newsel = self.items[idx + 1]
else:
newsel = self.items[0]
self.update_sel(wnd, newsel, bottom=True)
return newsel
@commandid('selectitemlist.prev')
@norec
@norerun
def sel_prev(self, wnd):
bottom = None
if not self.items:
newsel = None
elif self.cursel is None:
newsel = self.items[-1]
bottom = True
else:
try:
idx = self.items.index(self.cursel)
except ValueError:
newsel = self.items[-1]
bottom = True
else:
if idx > 0:
newsel = self.items[idx - 1]
else:
newsel = self.items[-1]
bottom = True
self.update_sel(wnd, newsel, bottom=bottom)
return newsel