forked from FaithLife-Community/LogosLinuxInstaller
-
Notifications
You must be signed in to change notification settings - Fork 0
/
tui_screen.py
483 lines (388 loc) · 15.3 KB
/
tui_screen.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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
import logging
import time
from pathlib import Path
import curses
import sys
import config
import installer
import system
import tui_curses
import utils
if system.have_dep("dialog"):
import tui_dialog
class Screen:
def __init__(self, app, screen_id, queue, event):
self.app = app
self.stdscr = ""
self.screen_id = screen_id
self.choice = "Processing"
self.queue = queue
self.event = event
# running:
# This var indicates either whether:
# A CursesScreen has already submitted its choice to the choice_q, or
# The var indicates whether a Dialog has already started. If the dialog has already started,
# then the program will not display the dialog again in order to prevent phantom key presses.
# 0 = not submitted or not started
# 1 = submitted or started
# 2 = none or finished
self.running = 0
def __str__(self):
return f"Curses Screen"
def display(self):
pass
def get_stdscr(self):
return self.app.stdscr
def get_screen_id(self):
return self.screen_id
def get_choice(self):
return self.choice
def wait_event(self):
self.event.wait()
def is_set(self):
return self.event.is_set()
class CursesScreen(Screen):
def submit_choice_to_queue(self):
if self.running == 0 and self.choice != "Processing":
self.app.choice_q.put(self.choice)
self.running = 1
class DialogScreen(Screen):
def submit_choice_to_queue(self):
if self.running == 1 and self.choice != "Processing":
self.app.choice_q.put(self.choice)
self.running = 2
class ConsoleScreen(CursesScreen):
def __init__(self, app, screen_id, queue, event, title, subtitle, title_start_y):
super().__init__(app, screen_id, queue, event)
self.stdscr = self.app.get_main_window()
self.title = title
self.subtitle = subtitle
self.title_start_y = title_start_y
def __str__(self):
return f"Curses Console Screen"
def display(self):
self.stdscr.erase()
subtitle_start = tui_curses.title(self.app, self.title, self.title_start_y)
tui_curses.title(self.app, self.subtitle, subtitle_start + 1)
self.stdscr.addstr(3, 2, f"---Console---")
recent_messages = logging.console_log[-6:]
for i, message in enumerate(recent_messages, 1):
message_lines = tui_curses.wrap_text(self.app, message)
for j, line in enumerate(message_lines):
if 2 + j < self.app.window_height:
self.stdscr.addstr(2 + i, 2, f"{message}")
self.stdscr.noutrefresh()
curses.doupdate()
class MenuScreen(CursesScreen):
def __init__(self, app, screen_id, queue, event, question, options, height=None, width=None, menu_height=8):
super().__init__(app, screen_id, queue, event)
self.stdscr = self.app.get_menu_window()
self.question = question
self.options = options
self.height = height
self.width = width
self.menu_height = menu_height
def __str__(self):
return f"Curses Menu Screen"
def display(self):
self.stdscr.erase()
self.choice = tui_curses.MenuDialog(
self.app,
self.question,
self.options
).run()
if self.choice is not None and not self.choice == "" and not self.choice == "Processing":
config.current_option = 0
config.current_page = 0
self.submit_choice_to_queue()
self.stdscr.noutrefresh()
curses.doupdate()
def get_question(self):
return self.question
def set_options(self, new_options):
self.options = new_options
self.app.menu_options = new_options
class ConfirmScreen(MenuScreen):
def __init__(self, app, screen_id, queue, event, question, no_text, secondary, options=["Yes", "No"]):
super().__init__(app, screen_id, queue, event, question, options,
height=None, width=None, menu_height=8)
self.no_text = no_text
self.secondary = secondary
def __str__(self):
return f"Curses Confirm Screen"
def display(self):
self.stdscr.erase()
self.choice = tui_curses.MenuDialog(
self.app,
self.secondary + "\n" + self.question,
self.options
).run()
if self.choice is not None and not self.choice == "" and not self.choice == "Processing":
config.current_option = 0
config.current_page = 0
if self.choice == "No":
logging.critical(self.no_text)
self.submit_choice_to_queue()
self.stdscr.noutrefresh()
curses.doupdate()
class InputScreen(CursesScreen):
def __init__(self, app, screen_id, queue, event, question, default):
super().__init__(app, screen_id, queue, event)
self.stdscr = self.app.get_menu_window()
self.question = question
self.default = default
self.dialog = tui_curses.UserInputDialog(
self.app,
self.question,
self.default
)
def __str__(self):
return f"Curses Input Screen"
def display(self):
self.stdscr.erase()
self.choice = self.dialog.run()
if not self.choice == "Processing":
self.submit_choice_to_queue()
self.stdscr.noutrefresh()
curses.doupdate()
def get_question(self):
return self.question
def get_default(self):
return self.default
class PasswordScreen(InputScreen):
def __init__(self, app, screen_id, queue, event, question, default):
super().__init__(app, screen_id, queue, event, question, default)
self.dialog = tui_curses.PasswordDialog(
self.app,
self.question,
self.default
)
def __str__(self):
return f"Curses Password Screen"
def display(self):
self.stdscr.erase()
self.choice = self.dialog.run()
if not self.choice == "Processing":
self.submit_choice_to_queue()
utils.send_task(self.app, "INSTALLING_PW")
self.stdscr.noutrefresh()
curses.doupdate()
class TextScreen(CursesScreen):
def __init__(self, app, screen_id, queue, event, text, wait):
super().__init__(app, screen_id, queue, event)
self.stdscr = self.app.get_menu_window()
self.text = text
self.wait = wait
self.spinner_index = 0
def __str__(self):
return f"Curses Text Screen"
def display(self):
self.stdscr.erase()
text_start_y, text_lines = tui_curses.text_centered(self.app, self.text)
if self.wait:
self.spinner_index = tui_curses.spinner(self.app, self.spinner_index, text_start_y + len(text_lines) + 1)
time.sleep(0.1)
self.stdscr.noutrefresh()
curses.doupdate()
def get_text(self):
return self.text
class MenuDialog(DialogScreen):
def __init__(self, app, screen_id, queue, event, question, options, height=None, width=None, menu_height=8):
super().__init__(app, screen_id, queue, event)
self.stdscr = self.app.get_menu_window()
self.question = question
self.options = options
self.height = height
self.width = width
self.menu_height = menu_height
def __str__(self):
return f"PyDialog Menu Screen"
def display(self):
if self.running == 0:
self.running = 1
_, _, self.choice = tui_dialog.menu(self.app, self.question, self.options, self.height, self.width,
self.menu_height)
self.submit_choice_to_queue()
def get_question(self):
return self.question
def set_options(self, new_options):
self.options = new_options
class InputDialog(DialogScreen):
def __init__(self, app, screen_id, queue, event, question, default):
super().__init__(app, screen_id, queue, event)
self.stdscr = self.app.get_menu_window()
self.question = question
self.default = default
def __str__(self):
return f"PyDialog Input Screen"
def display(self):
if self.running == 0:
self.running = 1
self.choice = tui_dialog.directory_picker(self.app, self.default)
if self.choice:
self.choice = Path(self.choice)
self.submit_choice_to_queue()
def get_question(self):
return self.question
def get_default(self):
return self.default
class PasswordDialog(InputDialog):
def __init__(self, app, screen_id, queue, event, question, default):
super().__init__(app, screen_id, queue, event, question, default)
def __str__(self):
return f"PyDialog Password Screen"
def display(self):
if self.running == 0:
self.running = 1
_, self.choice = tui_dialog.password(self.app, self.question, init=self.default)
self.submit_choice_to_queue()
utils.send_task(self.app, "INSTALLING_PW")
class ConfirmDialog(DialogScreen):
def __init__(self, app, screen_id, queue, event, question, no_text, secondary, yes_label="Yes", no_label="No"):
super().__init__(app, screen_id, queue, event)
self.stdscr = self.app.get_menu_window()
self.question = question
self.no_text = no_text
self.secondary = secondary
self.yes_label = yes_label
self.no_label = no_label
def __str__(self):
return f"PyDialog Confirm Screen"
def display(self):
if self.running == 0:
self.running = 1
self.choice = tui_dialog.confirm(self.app, self.secondary + self.question,
self.yes_label, self.no_label)
if self.choice == "cancel":
self.choice = self.no_label
logging.critical(self.no_text)
else:
self.choice = self.yes_label
self.submit_choice_to_queue()
def get_question(self):
return self.question
class TextDialog(DialogScreen):
def __init__(self, app, screen_id, queue, event, text, wait=False, percent=None, height=None, width=None,
title=None, backtitle=None, colors=True):
super().__init__(app, screen_id, queue, event)
self.stdscr = self.app.get_menu_window()
self.text = text
self.percent = percent
self.wait = wait
self.height = height
self.width = width
self.title = title
self.backtitle = backtitle
self.colors = colors
self.lastpercent = 0
def __str__(self):
return f"PyDialog Text Screen"
def display(self):
if self.running == 0:
if self.wait:
self.running = 1
if config.INSTALL_STEPS_COUNT > 0:
self.percent = installer.get_progress_pct(config.INSTALL_STEP, config.INSTALL_STEPS_COUNT)
else:
self.percent = 0
tui_dialog.progress_bar(self, self.text, self.percent)
self.lastpercent = self.percent
else:
tui_dialog.text(self, self.text)
elif self.running == 1:
if self.wait:
if config.INSTALL_STEPS_COUNT > 0:
self.percent = installer.get_progress_pct(config.INSTALL_STEP, config.INSTALL_STEPS_COUNT)
else:
self.percent = 0
# tui_dialog.update_progress_bar(self, self.percent, self.text, True)
if self.lastpercent != self.percent:
tui_dialog.progress_bar(self, self.text, self.percent)
if self.percent == 100:
tui_dialog.stop_progress_bar(self)
self.running = 2
self.wait = False
time.sleep(0.1)
def get_text(self):
return self.text
class TaskListDialog(DialogScreen):
def __init__(self, app, screen_id, queue, event, text, elements, percent,
height=None, width=None, title=None, backtitle=None, colors=True):
super().__init__(app, screen_id, queue, event)
self.stdscr = self.app.get_menu_window()
self.text = text
self.elements = elements if elements is not None else {}
self.percent = percent
self.height = height
self.width = width
self.title = title
self.backtitle = backtitle
self.colors = colors
self.updated = False
def __str__(self):
return f"PyDialog Task List Screen"
def display(self):
if self.running == 0:
tui_dialog.tasklist_progress_bar(self, self.text, self.percent, self.elements,
self.height, self.width, self.title, self.backtitle, self.colors)
self.running = 1
elif self.running == 1:
if self.updated:
tui_dialog.tasklist_progress_bar(self, self.text, self.percent, self.elements,
self.height, self.width, self.title, self.backtitle, self.colors)
else:
pass
time.sleep(0.1)
def set_text(self, text):
self.text = text
self.updated = True
def set_percent(self, percent):
self.percent = percent
self.updated = True
def set_elements(self, elements):
self.elements = elements
self.updated = True
def get_text(self):
return self.text
class BuildListDialog(DialogScreen):
def __init__(self, app, screen_id, queue, event, question, options, list_height=None, height=None, width=None):
super().__init__(app, screen_id, queue, event)
self.stdscr = self.app.get_menu_window()
self.question = question
self.options = options
self.height = height
self.width = width
self.list_height = list_height
def __str__(self):
return f"PyDialog Build List Screen"
def display(self):
if self.running == 0:
self.running = 1
code, self.choice = tui_dialog.buildlist(self.app, self.question, self.options, self.height, self.width,
self.list_height)
self.running = 2
def get_question(self):
return self.question
def set_options(self, new_options):
self.options = new_options
class CheckListDialog(DialogScreen):
def __init__(self, app, screen_id, queue, event, question, options, list_height=None, height=None, width=None):
super().__init__(app, screen_id, queue, event)
self.stdscr = self.app.get_menu_window()
self.question = question
self.options = options
self.height = height
self.width = width
self.list_height = list_height
def __str__(self):
return f"PyDialog Check List Screen"
def display(self):
if self.running == 0:
self.running = 1
code, self.choice = tui_dialog.checklist(self.app, self.question, self.options, self.height, self.width,
self.list_height)
self.running = 2
def get_question(self):
return self.question
def set_options(self, new_options):
self.options = new_options