listpick 0.1.13.58__py3-none-any.whl → 0.1.13.59__py3-none-any.whl

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.
listpick/listpick_app.py CHANGED
@@ -1235,7 +1235,7 @@ class Picker:
1235
1235
  while True:
1236
1236
  h, w = stdscr.getmaxyx()
1237
1237
 
1238
- choose_opts_widths = get_column_widths(options)
1238
+ choose_opts_widths = get_column_widths(options, unicode_char_width=self.unicode_char_width)
1239
1239
  window_width = min(max(sum(choose_opts_widths) + 6, 50) + 6, w)
1240
1240
  window_height = min(h//2, max(6, len(options)+3))
1241
1241
 
@@ -3160,7 +3160,7 @@ def main() -> None:
3160
3160
  function_data["display_infobox"] = True
3161
3161
  function_data["infobox_items"] = [["1"], ["2"], ["3"]]
3162
3162
  function_data["infobox_title"] = "Title"
3163
- function_data["footer_string"] = "Title"
3163
+ # function_data["footer_string"] = "Title"
3164
3164
  function_data["highlights"] = highlights
3165
3165
  function_data["show_footer"] = False
3166
3166
  # function_data["debug"] = True
@@ -0,0 +1,202 @@
1
+ """
2
+ footer.py
3
+ Lines to be displayed on the help screen.
4
+
5
+ Author: GrimAndGreedy
6
+ License: MIT
7
+ """
8
+
9
+ import curses
10
+ import logging
11
+
12
+ logger = logging.getLogger('picker_log')
13
+
14
+ class Footer:
15
+ def __init__(self, stdscr, colours_start, get_state_function):
16
+ """
17
+ stdscr: curses screen object
18
+ colours_start: base colour pair index
19
+ get_state_callback: function that returns a dict with all required data for rendering
20
+ """
21
+ self.stdscr = stdscr
22
+ self.colours_start = colours_start
23
+ self.get_state = get_state_function
24
+ self.height = 0
25
+
26
+ def draw(self, h, w):
27
+ """
28
+ Draw the footer. Must be implemented by subclasses.
29
+ """
30
+ raise NotImplementedError
31
+
32
+ class StandardFooter(Footer):
33
+ def __init__(self, stdscr, colours_start, get_state_function):
34
+ """
35
+ stdscr: curses screen object
36
+ colours_start: base colour pair index
37
+ get_state_callback: function that returns a dict with all required data for rendering
38
+ """
39
+ self.stdscr = stdscr
40
+ self.colours_start = colours_start
41
+ self.get_state = get_state_function
42
+ self.height = 3
43
+ def draw(self, h, w):
44
+ state = self.get_state()
45
+
46
+ # Fill background
47
+ for i in range(3):
48
+ self.stdscr.addstr(h-3+i, 0, ' '*(w-1), curses.color_pair(self.colours_start+20))
49
+
50
+ if state["filter_query"]:
51
+ self.stdscr.addstr(h - 2, 2, f" Filter: {state['filter_query']} "[:w-40], curses.color_pair(self.colours_start+20) | curses.A_BOLD)
52
+ if state["search_query"]:
53
+ self.stdscr.addstr(h - 3, 2, f" Search: {state['search_query']} [{state['search_index']}/{state['search_count']}] "[:w-3], curses.color_pair(self.colours_start+20) | curses.A_BOLD)
54
+ if state["user_opts"]:
55
+ self.stdscr.addstr(h - 1, 2, f" Opts: {state['user_opts']} "[:w-3], curses.color_pair(self.colours_start+20) | curses.A_BOLD)
56
+
57
+ # Sort info
58
+ sort_column_info = f"{state['sort_column'] if state['sort_column'] is not None else 'None'}"
59
+ sort_method_info = f"{state['SORT_METHODS'][state['columns_sort_method'][state['sort_column']]]}" if state['sort_column'] is not None else "NA"
60
+ sort_order_info = "Desc." if state["sort_reverse"] else "Asc."
61
+ sort_order_info = "▼" if state["sort_reverse"][state['sort_column']] else "▲"
62
+ sort_disp_str = f" Sort: ({sort_column_info}, {sort_method_info}, {sort_order_info}) "
63
+ self.stdscr.addstr(h - 2, w-35, f"{sort_disp_str:>34}", curses.color_pair(self.colours_start+20))
64
+
65
+ if state["footer_string"]:
66
+ # footer_string_width = min(w-1, max(len(state["footer_string"]), 50))
67
+ # disp_string = f"{state['footer_string'][:footer_string_width]:>{footer_string_width-1}} "
68
+ # self.stdscr.addstr(h - 1, w-footer_string_width-1, " "*footer_string_width, curses.color_pair(self.colours_start+24))
69
+ # self.stdscr.addstr(h - 1, w-footer_string_width-1, f"{disp_string}", curses.color_pair(self.colours_start+24))
70
+
71
+ # disp_string = f"{footer_string:>{footer_string_width-1}} "
72
+ # self.stdscr.addstr(h - 1, w-footer_string_width-1, " "*footer_string_width, curses.color_pair(self.colours_start+24))
73
+ # self.stdscr.addstr(h - 1, w-footer_string_width-1, f"{disp_string}", curses.color_pair(self.colours_start+24))
74
+
75
+ footer_string_width = min(w-1, len(state["footer_string"])+2)
76
+
77
+ disp_string = f"{state["footer_string"][:footer_string_width]}"
78
+ disp_string = f" {disp_string:>{footer_string_width-2}} "
79
+ self.stdscr.addstr(h - 1, w-footer_string_width-1, " "*footer_string_width, curses.color_pair(self.colours_start+24))
80
+ self.stdscr.addstr(h - 1, w-footer_string_width-1, f"{disp_string}", curses.color_pair(self.colours_start+24))
81
+
82
+
83
+ else:
84
+ select_mode = "Cursor"
85
+ if state["is_selecting"]: select_mode = "Visual Selection"
86
+ elif state["is_deselecting"]: select_mode = "Visual deselection"
87
+ self.stdscr.addstr(h - 1, w-35, f"{select_mode:>33} ", curses.color_pair(self.colours_start+20))
88
+
89
+ # Cursor & selection info
90
+ selected_count = sum(state["selections"].values())
91
+ if state["paginate"]:
92
+ cursor_disp_str = f" {state['cursor_pos']+1}/{len(state['indexed_items'])} Page {state['cursor_pos']//state['items_per_page']}/{len(state['indexed_items'])} Selected {selected_count}"
93
+ else:
94
+ cursor_disp_str = f" {state['cursor_pos']+1}/{len(state['indexed_items'])} | Selected {selected_count}"
95
+ self.stdscr.addstr(h - 3, w-35, f"{cursor_disp_str:>33} ", curses.color_pair(self.colours_start+20))
96
+
97
+ self.stdscr.refresh()
98
+
99
+
100
+
101
+ class CompactFooter(Footer):
102
+ def __init__(self, stdscr, colours_start, get_state_function):
103
+ """
104
+ stdscr: curses screen object
105
+ colours_start: base colour pair index
106
+ get_state_callback: function that returns a dict with all required data for rendering
107
+ """
108
+ self.stdscr = stdscr
109
+ self.colours_start = colours_start
110
+ self.get_state = get_state_function
111
+ self.height = 1
112
+
113
+ def draw(self, h, w):
114
+ state = self.get_state()
115
+
116
+ # Fill background
117
+ if state["search_query"]: self.height = 3
118
+ elif state["filter_query"]: self.height = 2
119
+ elif state["user_opts"]: self.height = 1
120
+ elif state["footer_string"]: self.height = 2
121
+ else: self.height = 1
122
+ for i in range(self.height):
123
+ self.stdscr.addstr(h-(i+1), 0, ' '*(w-1), curses.color_pair(self.colours_start+20))
124
+
125
+ if state["user_opts"]:
126
+ self.stdscr.addstr(h - 1, 2, f" Opts: {state['user_opts']} "[:w-3], curses.color_pair(self.colours_start+20) | curses.A_BOLD)
127
+ if state["filter_query"]:
128
+ self.stdscr.addstr(h - 2, 2, f" Filter: {state['filter_query']} "[:w-40], curses.color_pair(self.colours_start+20) | curses.A_BOLD)
129
+ if state["search_query"]:
130
+ self.stdscr.addstr(h - 3, 2, f" Search: {state['search_query']} [{state['search_index']}/{state['search_count']}] "[:w-3], curses.color_pair(self.colours_start+20) | curses.A_BOLD)
131
+
132
+ right_width = 40
133
+ # Sort info
134
+ sort_column_info = f"{state['sort_column'] if state['sort_column'] is not None else 'None'}"
135
+ sort_method_info = f"{state['SORT_METHODS'][state['columns_sort_method'][state['sort_column']]]}" if state['sort_column'] is not None else "NA"
136
+ sort_order_info = "Desc." if state["sort_reverse"][state['sort_column']] else "Asc."
137
+ sort_order_info = "▼" if state["sort_reverse"][state['sort_column']] else "▲"
138
+ sort_disp_str = f" ({sort_column_info}, {sort_method_info}, {sort_order_info}) "
139
+ # self.stdscr.addstr(h - 2, w-right_width, f"{sort_disp_str:>{right_width-1}}", curses.color_pair(self.colours_start+20))
140
+
141
+ if state["footer_string"]:
142
+ footer_string_width = min(w-1, len(state["footer_string"])+2)
143
+
144
+ disp_string = f"{state["footer_string"][:footer_string_width]}"
145
+ disp_string = f" {disp_string:>{footer_string_width-2}} "
146
+ self.stdscr.addstr(h - 1, w-footer_string_width-1, " "*footer_string_width, curses.color_pair(self.colours_start+24))
147
+ self.stdscr.addstr(h - 1, w-footer_string_width-1, f"{disp_string}", curses.color_pair(self.colours_start+24))
148
+ selected_count = sum(state["selections"].values())
149
+ if state["paginate"]:
150
+ cursor_disp_str = f" {state['cursor_pos']+1}/{len(state['indexed_items'])} Page {state['cursor_pos']//state['items_per_page']}/{len(state['indexed_items'])} Selected {selected_count}"
151
+ else:
152
+ cursor_disp_str = f"{sort_disp_str} [{selected_count}] {state['cursor_pos']+1}/{len(state['indexed_items'])}"
153
+ self.stdscr.addstr(h-2, w-right_width, f"{cursor_disp_str:>{right_width-2}}"[:right_width-1], curses.color_pair(self.colours_start+20))
154
+ else:
155
+ # Cursor & selection info
156
+ selected_count = sum(state["selections"].values())
157
+ if state["paginate"]:
158
+ cursor_disp_str = f" {state['cursor_pos']+1}/{len(state['indexed_items'])} Page {state['cursor_pos']//state['items_per_page']}/{len(state['indexed_items'])} Selected {selected_count}"
159
+ else:
160
+ cursor_disp_str = f"{sort_disp_str} [{selected_count}] {state['cursor_pos']+1}/{len(state['indexed_items'])}"
161
+ self.stdscr.addstr(h - 1, w-right_width, f"{cursor_disp_str:>{right_width-2}}"[:right_width-1], curses.color_pair(self.colours_start+20))
162
+
163
+ self.stdscr.refresh()
164
+
165
+ class NoFooter(Footer):
166
+ def __init__(self, stdscr, colours_start, get_state_function):
167
+ """
168
+ stdscr: curses screen object
169
+ colours_start: base colour pair index
170
+ get_state_callback: function that returns a dict with all required data for rendering
171
+ """
172
+ self.stdscr = stdscr
173
+ self.colours_start = colours_start
174
+ self.get_state = get_state_function
175
+ self.height = 0
176
+ def draw(self, h, w):
177
+ state = self.get_state()
178
+
179
+ if state["search_query"]: self.height = 3
180
+ elif state["filter_query"]: self.height = 2
181
+ elif state["user_opts"]: self.height = 1
182
+ elif state["footer_string"]: self.height = 1
183
+ else: self.height = 0
184
+
185
+ for i in range(self.height):
186
+ self.stdscr.addstr(h-(i+1), 0, ' '*(w-1), curses.color_pair(self.colours_start+20))
187
+
188
+ if state["user_opts"]:
189
+ self.stdscr.addstr(h - 1, 2, f" Opts: {state['user_opts']} "[:w-3], curses.color_pair(self.colours_start+20) | curses.A_BOLD)
190
+ if state["filter_query"]:
191
+ self.stdscr.addstr(h - 2, 2, f" Filter: {state['filter_query']} "[:w-40], curses.color_pair(self.colours_start+20) | curses.A_BOLD)
192
+ if state["search_query"]:
193
+ self.stdscr.addstr(h - 3, 2, f" Search: {state['search_query']} [{state['search_index']}/{state['search_count']}] "[:w-3], curses.color_pair(self.colours_start+20) | curses.A_BOLD)
194
+ self.height = 3
195
+
196
+
197
+ if state["footer_string"]:
198
+ footer_string_width = min(w-1, len(state["footer_string"])+2)
199
+ disp_string = f"{state["footer_string"][:footer_string_width]}"
200
+ disp_string = f" {disp_string:>{footer_string_width-2}} "
201
+ self.stdscr.addstr(h - 1, w-footer_string_width-1, " "*footer_string_width, curses.color_pair(self.colours_start+24))
202
+ self.stdscr.addstr(h - 1, w-footer_string_width-1, f"{disp_string}", curses.color_pair(self.colours_start+24))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: listpick
3
- Version: 0.1.13.58
3
+ Version: 0.1.13.59
4
4
  Summary: Listpick is a powerful TUI data tool for creating TUI apps or viewing/comparing tabulated data.
5
5
  Home-page: https://github.com/grimandgreedy/listpick
6
6
  Author: Grim
@@ -1,10 +1,10 @@
1
1
  listpick/__init__.py,sha256=ExXc97-bibodH--wlwpQivl0zCNR5D1hvpvrf7OBofU,154
2
2
  listpick/__main__.py,sha256=wkCjDdqw093W27yWwnlC3nG_sMRKaIad7hHHWy0RBgY,193
3
- listpick/listpick_app.py,sha256=4XuOdhtslhNvVnwsAwuAY3v93CriOBQMFqkpfCvPuz4,165105
4
- listpick/listpick_app_problem_branch.py,sha256=gystrBg75SqmUa3aUcL-AM7bv_oYJ3kimQKDCVic9Co,166625
3
+ listpick/listpick_app.py,sha256=cAZXi69fk_1dcmWF36FfTgEptLyzLQRSdBYG8qCY9bA,165151
5
4
  listpick/ui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
5
  listpick/ui/build_help.py,sha256=_rVKKrX3HfFJtw-pyeNb2lQWbml4-AAw8sZIUYGn97Y,8731
7
6
  listpick/ui/footer.py,sha256=s1L68MNmhWwbWRy0mn0ChmnE_dMQBAzNlTv917pyHE0,10673
7
+ listpick/ui/footer_1.py,sha256=Mpn0gFAnX_Ely-Jl5KPP6sdZRnk8makt8EVBh9wdr4Y,10710
8
8
  listpick/ui/help_screen.py,sha256=zbfGIgb-IXtATpl4_Sx7nPbsnRXZ7eiMYlCKGS9EFmw,5608
9
9
  listpick/ui/input_field.py,sha256=eyoWHoApdZybjfXcp7Eth7xwb-C-856ZVnq5j_Q3Ojs,30412
10
10
  listpick/ui/keys.py,sha256=TzaadgBP_rC7jbp--RFJZDOkHd0EB4K1wToDTiVs6CI,13029
@@ -24,9 +24,9 @@ listpick/utils/searching.py,sha256=Xk5UIqamNHL2L90z3ACB_Giqdpi9iRKoAJ6pKaqaD7Q,3
24
24
  listpick/utils/sorting.py,sha256=WZZiVlVA3Zkcpwji3U5SNFlQ14zVEk3cZJtQirBkecQ,5329
25
25
  listpick/utils/table_to_list_of_lists.py,sha256=T-i-nV1p6g8UagdgUPKrhIGpKY_YXZDxf4xZzcPepNA,7635
26
26
  listpick/utils/utils.py,sha256=_4HW0p1gnundsTJcKsSsIKCZxy3DtolbxjBpuYQyFBw,12948
27
- listpick-0.1.13.58.dist-info/licenses/LICENSE.txt,sha256=2mP-MRHJptADDNE9VInMNg1tE-C6Qv93Z4CCQKrpg9w,1061
28
- listpick-0.1.13.58.dist-info/METADATA,sha256=hH59V4Klb1XAOnkPY_-4mUz6hxePi4QvzlZPvrzvx0c,7988
29
- listpick-0.1.13.58.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
30
- listpick-0.1.13.58.dist-info/entry_points.txt,sha256=-QCf_BKIkUz35Y9nkYpjZWs2Qg0KfRna2PAs5DnF6BE,43
31
- listpick-0.1.13.58.dist-info/top_level.txt,sha256=5mtsGEz86rz3qQDe0D463gGjAfSp6A3EWg4J4AGYr-Q,9
32
- listpick-0.1.13.58.dist-info/RECORD,,
27
+ listpick-0.1.13.59.dist-info/licenses/LICENSE.txt,sha256=2mP-MRHJptADDNE9VInMNg1tE-C6Qv93Z4CCQKrpg9w,1061
28
+ listpick-0.1.13.59.dist-info/METADATA,sha256=bD3N7PxFIQnVXf080zULv-TjMr9ia7RL8pLSZO2smYY,7988
29
+ listpick-0.1.13.59.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
30
+ listpick-0.1.13.59.dist-info/entry_points.txt,sha256=-QCf_BKIkUz35Y9nkYpjZWs2Qg0KfRna2PAs5DnF6BE,43
31
+ listpick-0.1.13.59.dist-info/top_level.txt,sha256=5mtsGEz86rz3qQDe0D463gGjAfSp6A3EWg4J4AGYr-Q,9
32
+ listpick-0.1.13.59.dist-info/RECORD,,