-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.py
198 lines (166 loc) · 6.7 KB
/
main.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
import os
import time
os.system("cls")
SCREEN_ITEMS = {
"foreground-color": {
"name": "Foreground Color",
"items": {
"white": "37",
"black": "30",
"red": "31",
"green": "32",
"blue": "34",
"magenta": "35",
"cyan": "36",
"yellow": "33",
},
"selected": ""
},
"background-color": {
"name": "Background Color",
"items": {
"white": "47",
"black": "40",
"red": "41",
"green": "42",
"blue": "44",
"magenta": "45",
"cyan": "46",
"yellow": "43",
},
"selected": ""
},
"text-stlye": {
"name": "Text Style",
"items": {
"bold": "1",
"italic": "3",
"underline": "4",
"strikethrough": "9",
},
"selected": ""
}
}
# Formats any text with the given ANSI escape codes and returns it
def make_escaped_text(codes: list[str], text: str):
formatted_text = "\033[" + ";".join(codes) + "m" + text + "\033[0m"
return formatted_text
# Returns a printable (to the terminal) ANSI escape code sequence
def make_printable_escape_code(codes: list[str]):
# note the second backslash
code = "\\033[" + ";".join(codes) + "m"
return code
# Formats the selected ANSI escape codes into a string to be displayed to the user
def get_final_code():
codes = []
for key in SCREEN_ITEMS:
item_name = SCREEN_ITEMS[key]["selected"]
if not item_name:
continue
codes.append(SCREEN_ITEMS[key]["items"][item_name])
if not len(codes):
return "Maybe make a selection first ¯\\_(ツ)_/¯"
return make_printable_escape_code(codes) + make_escaped_text(codes, "TEXT HERE") + make_printable_escape_code(["0"])
# Prints the selected options nicely formatted next to the main menu entries
def print_selection(current_screen):
selection = SCREEN_ITEMS[current_screen]["selected"]
if selection:
print(":", make_escaped_text([SCREEN_ITEMS[current_screen]["items"][selection]], selection))
else:
print() # we need a linebreak if we got no selection
# This funny funtion uses some escape code trickery to place the cursor
# where we want to draw the window borders.
# It will draw the right (and left) border for the NEXT line
def draw_right_window_border(also_draw_left = False):
if also_draw_left:
# draw left border and then reset cursor to line start
print("│", end="\033[0G")
# move cursor X chars to right and draw border
print(f"\033[31C│", end="")
# move cursor to line start
print("\033[0G", end="\n" if also_draw_left else "")
# Handle all the screen rendering stuff
def push_screen(screen_key = ""):
# This is used to cleanup before we display a new screen
# move cursor to home ->
# move cursor few lines down to keep header ->
# delete everything until end of screen
print("\033[H" "\033[3E" "\033[0J", end="")
# home screen
if not screen_key or screen_key == "home":
draw_right_window_border()
print("│", "\033[1mMAIN MENU\033[0m")
# we want to have an empty line thus we need a left border as well
draw_right_window_border(also_draw_left=True)
for index, keys in enumerate(SCREEN_ITEMS.keys()):
draw_right_window_border()
print(f"┝ {index + 1})", SCREEN_ITEMS[keys]["name"], end="")
print_selection(keys)
time.sleep(0.1)
draw_right_window_border(also_draw_left=True)
draw_right_window_border()
print("┝", "9)", make_escaped_text(["31"], "Reset"))
time.sleep(0.1)
draw_right_window_border(also_draw_left=True)
draw_right_window_border()
print("┝", "0)", make_escaped_text(["32"], "Get Code"))
time.sleep(0.1)
print("└──────────────────────────────┘")
handle_navigation("home")
# all other screens
else:
draw_right_window_border()
print("│\033[1m", SCREEN_ITEMS[screen_key]["name"], "\033[0m")
draw_right_window_border(also_draw_left=True)
for index, (name, code) in enumerate(SCREEN_ITEMS[screen_key]["items"].items()):
draw_right_window_border()
print(f"┝ {index + 1})", make_escaped_text([code], "▆"), name)
time.sleep(0.05)
draw_right_window_border(also_draw_left=True)
draw_right_window_border()
print("┝", "0) Back")
print("└──────────────────────────────┘")
handle_navigation(screen_key)
# Handling user input for all screens
def handle_navigation(current_screen):
while True:
try:
# choice will be used to select the desired option
# we're going to do choice-1 further down to go zero-indexed
choice = int(input("> "))
if current_screen == "home":
if choice == 0:
print("\n", get_final_code(), "\n")
continue
if choice == 9:
for screen_key in SCREEN_ITEMS.keys():
SCREEN_ITEMS[screen_key]["selected"] = ""
push_screen()
# check if choice is valid
keys = list(SCREEN_ITEMS.keys())
if not choice - 1 in range(len(keys)):
raise ValueError
push_screen(keys[choice - 1]) # go to chosen screen
else: # all other screens
if choice == 0:
push_screen() # go to home screen
# check if choice is valid
keys = list(SCREEN_ITEMS[current_screen]["items"].keys())
if not choice - 1 in range(len(keys)):
raise ValueError
# user selected something
print(SCREEN_ITEMS[current_screen]["name"] + ":", keys[choice - 1], "selected")
# store what the user has selected
SCREEN_ITEMS[current_screen]["selected"] = keys[choice - 1]
time.sleep(1)
push_screen() # go to home screen
except ValueError:
print("Please choose a valid option")
continue
# header
print("┌──────────────────────────────┐")
print("│ \033[33;1mANSI Escape Code Generator\033[0m │")
print("├──────────────────────────────┤")
time.sleep(0.1)
# home screen
push_screen()