curses-utils2 0.2.0__tar.gz → 0.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {curses_utils2-0.2.0 → curses_utils2-0.3.0}/PKG-INFO +1 -1
- curses_utils2-0.3.0/curses_utils2/__init__.py +1 -0
- {curses_utils2-0.2.0 → curses_utils2-0.3.0}/curses_utils2/list1.py +7 -5
- {curses_utils2-0.2.0 → curses_utils2-0.3.0}/curses_utils2/list1m.py +1 -2
- {curses_utils2-0.2.0 → curses_utils2-0.3.0}/curses_utils2/list3.py +7 -5
- curses_utils2-0.2.0/curses_utils2/__init__.py +0 -1
- curses_utils2-0.2.0/curses_utils2/list2.py +0 -174
- {curses_utils2-0.2.0 → curses_utils2-0.3.0}/LICENSE +0 -0
- {curses_utils2-0.2.0 → curses_utils2-0.3.0}/README.rst +0 -0
- {curses_utils2-0.2.0 → curses_utils2-0.3.0}/curses_utils2/app.py +0 -0
- {curses_utils2-0.2.0 → curses_utils2-0.3.0}/curses_utils2/py.typed +0 -0
- {curses_utils2-0.2.0 → curses_utils2-0.3.0}/curses_utils2/text.py +0 -0
- {curses_utils2-0.2.0 → curses_utils2-0.3.0}/curses_utils2/win.py +0 -0
- {curses_utils2-0.2.0 → curses_utils2-0.3.0}/pyproject.toml +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = '0.3.0'
|
|
@@ -15,7 +15,7 @@ class ListProto(Protocol):
|
|
|
15
15
|
pass
|
|
16
16
|
|
|
17
17
|
|
|
18
|
-
class List:
|
|
18
|
+
class List: # pylint: disable=attribute-defined-outside-init
|
|
19
19
|
'''
|
|
20
20
|
A projection of an array of records r0...rX to a window lines of string s0...sY
|
|
21
21
|
where si = get_record_str(j) = rj -> str, s(i+1) = get_record_str(j+1), j < records_len()
|
|
@@ -24,19 +24,19 @@ class List:
|
|
|
24
24
|
|
|
25
25
|
def __init__(
|
|
26
26
|
self,
|
|
27
|
-
win: curses.window,
|
|
28
27
|
proto: ListProto,
|
|
29
28
|
current_color: int = curses.A_BOLD,
|
|
30
29
|
):
|
|
31
|
-
self.win = win
|
|
32
30
|
self.proto = proto
|
|
33
31
|
self.current_color = current_color
|
|
34
32
|
|
|
35
|
-
self.win.keypad(True)
|
|
36
|
-
|
|
37
33
|
self.cur = 0 # cursor y
|
|
38
34
|
self.idx = 0 # source index
|
|
39
35
|
|
|
36
|
+
def set_win(self, win: curses.window):
|
|
37
|
+
self.win = win
|
|
38
|
+
self.win.keypad(True)
|
|
39
|
+
|
|
40
40
|
def refresh(self):
|
|
41
41
|
self.win.erase()
|
|
42
42
|
len_ = self.proto.records_len()
|
|
@@ -44,6 +44,8 @@ class List:
|
|
|
44
44
|
rows, _ = self.win.getmaxyx()
|
|
45
45
|
if not self.idx < len_: # deleted
|
|
46
46
|
self.idx = len_ - 1
|
|
47
|
+
if not self.cur < rows: # new win < old win
|
|
48
|
+
self.cur = rows - 1
|
|
47
49
|
if (rows - self.cur) > (di := len_ - self.idx):
|
|
48
50
|
# gap at bottom
|
|
49
51
|
self.cur = rows - di
|
|
@@ -16,11 +16,10 @@ class List1m(List):
|
|
|
16
16
|
|
|
17
17
|
def __init__(
|
|
18
18
|
self,
|
|
19
|
-
win: curses.window,
|
|
20
19
|
proto: ListProto1m,
|
|
21
20
|
current_color: int = curses.A_BOLD,
|
|
22
21
|
):
|
|
23
|
-
super().__init__(
|
|
22
|
+
super().__init__(proto, current_color)
|
|
24
23
|
self.proto: ListProto1m = proto
|
|
25
24
|
|
|
26
25
|
def move_up(self, i: int):
|
|
@@ -16,26 +16,26 @@ class ListProto3(Protocol):
|
|
|
16
16
|
pass
|
|
17
17
|
|
|
18
18
|
|
|
19
|
-
class List3:
|
|
19
|
+
class List3: # pylint: disable=attribute-defined-outside-init
|
|
20
20
|
'List + every record projects to <height> window lines'
|
|
21
21
|
|
|
22
22
|
def __init__(
|
|
23
23
|
self,
|
|
24
|
-
win: curses.window,
|
|
25
24
|
proto: ListProto3,
|
|
26
25
|
height: int = 1,
|
|
27
26
|
current_color: int = curses.A_BOLD,
|
|
28
27
|
):
|
|
29
|
-
self.win = win
|
|
30
28
|
self.height = height
|
|
31
29
|
self.proto = proto
|
|
32
30
|
self.current_color = current_color
|
|
33
31
|
|
|
34
|
-
self.win.keypad(True)
|
|
35
|
-
|
|
36
32
|
self.cur = 0 # cursor y, = 0..(maxy // height), real cursor = cur * height
|
|
37
33
|
self.idx = 0 # source index
|
|
38
34
|
|
|
35
|
+
def set_win(self, win: curses.window):
|
|
36
|
+
self.win = win
|
|
37
|
+
self.win.keypad(True)
|
|
38
|
+
|
|
39
39
|
def addstr(self, i: int, g: Generator[str], attr: int = 0):
|
|
40
40
|
i2 = i * self.height
|
|
41
41
|
j = -1
|
|
@@ -62,6 +62,8 @@ class List3:
|
|
|
62
62
|
rows //= self.height
|
|
63
63
|
if not self.idx < len_: # deleted
|
|
64
64
|
self.idx = len_ - 1
|
|
65
|
+
if not self.cur < rows: # new win < old win
|
|
66
|
+
self.cur = rows - 1
|
|
65
67
|
if (rows - self.cur) > (di := len_ - self.idx):
|
|
66
68
|
# gap at bottom
|
|
67
69
|
self.cur = rows - di
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = '0.2.0'
|
|
@@ -1,174 +0,0 @@
|
|
|
1
|
-
import curses
|
|
2
|
-
from typing import Protocol
|
|
3
|
-
|
|
4
|
-
from .win import win_addstr
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
class ListProto2(Protocol):
|
|
8
|
-
def get_record_str(self, i: int) -> tuple[str, str]:
|
|
9
|
-
pass
|
|
10
|
-
|
|
11
|
-
def records_len(self) -> int:
|
|
12
|
-
pass
|
|
13
|
-
|
|
14
|
-
def refresh_win_deps(self):
|
|
15
|
-
pass
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
class List2:
|
|
19
|
-
'List + every record projects to 2 window lines'
|
|
20
|
-
|
|
21
|
-
def __init__(
|
|
22
|
-
self,
|
|
23
|
-
win: curses.window,
|
|
24
|
-
proto: ListProto2,
|
|
25
|
-
current_color: int = curses.A_BOLD,
|
|
26
|
-
):
|
|
27
|
-
self.win = win
|
|
28
|
-
self.proto = proto
|
|
29
|
-
self.current_color = current_color
|
|
30
|
-
|
|
31
|
-
self.win.keypad(True)
|
|
32
|
-
|
|
33
|
-
self.cur = 0 # cursor y, = 0..(maxy // 2), real cursor = cur * 2
|
|
34
|
-
self.idx = 0 # source index
|
|
35
|
-
|
|
36
|
-
def addstr(self, i: int, t: tuple[str, str], attr: int = 0):
|
|
37
|
-
i2 = i * 2
|
|
38
|
-
if attr:
|
|
39
|
-
win_addstr(self.win, i2, 0, t[0], attr=attr | curses.A_BOLD)
|
|
40
|
-
win_addstr(self.win, i2 + 1, 0, t[1], attr=attr | curses.A_DIM)
|
|
41
|
-
else:
|
|
42
|
-
# win_addstr(self.win, i2, 0, t[0], attr=curses.A_BOLD)
|
|
43
|
-
win_addstr(self.win, i2, 0, t[0])
|
|
44
|
-
win_addstr(self.win, i2 + 1, 0, t[1], attr=curses.A_DIM)
|
|
45
|
-
|
|
46
|
-
def refresh(self):
|
|
47
|
-
self.win.erase()
|
|
48
|
-
len_ = self.proto.records_len()
|
|
49
|
-
if len_:
|
|
50
|
-
rows, _ = self.win.getmaxyx()
|
|
51
|
-
rows //= 2
|
|
52
|
-
if not self.idx < len_: # deleted
|
|
53
|
-
self.idx = len_ - 1
|
|
54
|
-
if (rows - self.cur) > (di := len_ - self.idx):
|
|
55
|
-
# gap at bottom
|
|
56
|
-
self.cur = rows - di
|
|
57
|
-
self.cur = min(self.cur, self.idx)
|
|
58
|
-
for i in range(rows):
|
|
59
|
-
idx = self.idx - self.cur + i
|
|
60
|
-
if not idx < len_:
|
|
61
|
-
break
|
|
62
|
-
s = self.proto.get_record_str(idx)
|
|
63
|
-
if i == self.cur:
|
|
64
|
-
self.addstr(i, s, attr=self.current_color)
|
|
65
|
-
else:
|
|
66
|
-
self.addstr(i, s)
|
|
67
|
-
self.win.move(self.cur * 2, 0)
|
|
68
|
-
self.win.refresh()
|
|
69
|
-
self.proto.refresh_win_deps()
|
|
70
|
-
|
|
71
|
-
def scroll_top(self):
|
|
72
|
-
self.idx = self.cur = 0
|
|
73
|
-
self.refresh()
|
|
74
|
-
|
|
75
|
-
def scroll_bottom(self):
|
|
76
|
-
len_ = self.proto.records_len()
|
|
77
|
-
if not len_:
|
|
78
|
-
return
|
|
79
|
-
rows, _ = self.win.getmaxyx()
|
|
80
|
-
rows //= 2
|
|
81
|
-
self.cur = min(rows - 1, len_ - 1)
|
|
82
|
-
self.idx = len_ - 1
|
|
83
|
-
self.refresh()
|
|
84
|
-
|
|
85
|
-
def scroll_down(self):
|
|
86
|
-
len_ = self.proto.records_len()
|
|
87
|
-
if not len_ or not self.idx + 1 < len_:
|
|
88
|
-
return
|
|
89
|
-
rows, _ = self.win.getmaxyx()
|
|
90
|
-
rows //= 2
|
|
91
|
-
prev_s = self.proto.get_record_str(self.idx)
|
|
92
|
-
next_s = self.proto.get_record_str(self.idx + 1)
|
|
93
|
-
self.addstr(self.cur, prev_s)
|
|
94
|
-
if self.cur + 1 < rows:
|
|
95
|
-
self.cur += 1
|
|
96
|
-
else:
|
|
97
|
-
self.win.move(0, 0)
|
|
98
|
-
self.win.deleteln()
|
|
99
|
-
self.win.deleteln()
|
|
100
|
-
self.cur = rows - 1
|
|
101
|
-
self.addstr(self.cur, next_s, attr=self.current_color)
|
|
102
|
-
self.idx += 1
|
|
103
|
-
self.win.refresh()
|
|
104
|
-
self.proto.refresh_win_deps()
|
|
105
|
-
|
|
106
|
-
def scroll_up(self):
|
|
107
|
-
len_ = self.proto.records_len()
|
|
108
|
-
if not len_ or self.idx - 1 < 0:
|
|
109
|
-
return
|
|
110
|
-
prev_s = self.proto.get_record_str(self.idx)
|
|
111
|
-
next_s = self.proto.get_record_str(self.idx - 1)
|
|
112
|
-
self.addstr(self.cur, prev_s)
|
|
113
|
-
if self.cur > 0:
|
|
114
|
-
self.cur -= 1
|
|
115
|
-
else:
|
|
116
|
-
self.win.move(0, 0)
|
|
117
|
-
self.win.insdelln(2)
|
|
118
|
-
self.addstr(self.cur, next_s, attr=self.current_color)
|
|
119
|
-
self.idx -= 1
|
|
120
|
-
self.win.refresh()
|
|
121
|
-
self.proto.refresh_win_deps()
|
|
122
|
-
|
|
123
|
-
def scroll_page_down(self):
|
|
124
|
-
len_ = self.proto.records_len()
|
|
125
|
-
if not len_:
|
|
126
|
-
return
|
|
127
|
-
rows, _ = self.win.getmaxyx()
|
|
128
|
-
rows //= 2
|
|
129
|
-
idx = self.idx + rows
|
|
130
|
-
if idx < len_:
|
|
131
|
-
self.idx = idx
|
|
132
|
-
self.refresh()
|
|
133
|
-
else:
|
|
134
|
-
idx = len_ - 1
|
|
135
|
-
delta = idx - self.idx
|
|
136
|
-
if not delta:
|
|
137
|
-
self.scroll_bottom()
|
|
138
|
-
elif self.cur + delta < rows:
|
|
139
|
-
self.cur += delta
|
|
140
|
-
self.idx = idx
|
|
141
|
-
self.refresh()
|
|
142
|
-
else:
|
|
143
|
-
self.scroll_bottom()
|
|
144
|
-
|
|
145
|
-
def scroll_page_up(self):
|
|
146
|
-
len_ = self.proto.records_len()
|
|
147
|
-
if not len_:
|
|
148
|
-
return
|
|
149
|
-
rows, _ = self.win.getmaxyx()
|
|
150
|
-
rows //= 2
|
|
151
|
-
idx = self.idx - rows
|
|
152
|
-
if idx >= 0:
|
|
153
|
-
self.idx = idx
|
|
154
|
-
self.refresh()
|
|
155
|
-
else:
|
|
156
|
-
self.scroll_top()
|
|
157
|
-
|
|
158
|
-
def handle_input(self, ch: int) -> bool:
|
|
159
|
-
char = chr(ch)
|
|
160
|
-
if char.upper() == 'J' or ch == curses.KEY_DOWN: # Down or J
|
|
161
|
-
self.scroll_down()
|
|
162
|
-
elif char.upper() == 'K' or ch == curses.KEY_UP: # Up or K
|
|
163
|
-
self.scroll_up()
|
|
164
|
-
elif char == 'g' or ch == curses.KEY_HOME: # Move to top
|
|
165
|
-
self.scroll_top()
|
|
166
|
-
elif char == 'G' or ch == curses.KEY_END: # Move to last item
|
|
167
|
-
self.scroll_bottom()
|
|
168
|
-
elif ch == curses.KEY_NPAGE: # Page down
|
|
169
|
-
self.scroll_page_down()
|
|
170
|
-
elif ch == curses.KEY_PPAGE: # Page up
|
|
171
|
-
self.scroll_page_up()
|
|
172
|
-
else:
|
|
173
|
-
return False
|
|
174
|
-
return True
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|