def print_modulename(scr: Window, name: str) -> None: """ Prints the module name in the standard format. """ scr.addstr("Module: ", curses.color_pair(0)) scr.addstr(name, curses.color_pair(6)) scr.addstr("\n\n", curses.color_pair(0))
def main(scr: Window): wards.setup(scr) wards.print_modulename(scr, NAME) wards.print_controls(scr, (("ESC", "Quit the module."), ("[1, 5]", "Add wire of corresponding color."), ("TAB", "Reset."))) scr.addstr("This module is not yet completed!\n\n", curses.color_pair(0)) scr.addstr("Press any key to exit.", curses.color_pair(3)) scr.getch()
def menu(scr: Window, modules: Kitalogue) -> Optional[KitProcedure]: """ Enters the main menu state. Returns a KitProcedure as selected by the user. Note: The name modules refers to KTaNE modules, not Python modules. """ # Standard setup. wards.setup(scr) # Print a welcome message. scr.addstr("Hi, welcome to ") scr.addstr("ktane-defusekit", curses.color_pair(2)) scr.addstr("!\n", curses.color_pair(0)) scr.addstr("This is an interactive bomb defusal manual ") scr.addstr("for Keep Talking and Nobody Explodes.") scr.addstr("\n\n") # Print the controls. wards.print_controls(scr, (("ESC", "Quit the program."), ("UP, DOWN", "Navigate the module list."), ("[type]", "Type module name into text prompt."), ("TAB", "Autocomplete module name."), ("ENTER", "Select module to run."))) # Print modules, and store their coordinates for later use. module_coords: List[Coord] = [] # coords for updating selection cursor scr.addstr("Available Modules:") for i, mod in enumerate(modules): scr.addstr("\n") scr.addstr((str(i) + ") ").rjust(6)) scr.addstr(mod, curses.color_pair(6)) module_coords.append(scr.getyx()) scr.addstr("\n\n") def update_cursor(selectindex: Optional[int]) -> None: for i, pos in enumerate(module_coords): scr.move(pos[0], pos[1]) scr.clrtoeol() if selectindex is not None and i == selectindex: scr.addstr(" <--", curses.color_pair(2)) # Print the inputbox, and store its coordinate. scr.addstr(">>> ", curses.color_pair(2)) inputbox_coord = scr.getyx() # coord for updating input text def update_inputbox(inputstring: str, valid: bool): scr.move(inputbox_coord[0], inputbox_coord[1]) scr.clrtoeol() clr = curses.color_pair(0) if valid: clr = curses.color_pair(6) scr.addstr(inputstring, clr) # Enter the input loop. selectindex = None inputstring = "" valid = False while True: c = scr.getch() if c == 27: # Esc return None elif c == 10 and valid: # Enter return modules[inputstring] elif c in (258, 259): # Down, Up if selectindex is None: selectindex = 0 # Initial elif c == 258: selectindex += 1 # Down else: selectindex -= 1 # Up selectindex = selectindex % len(module_coords) inputstring = list(modules.keys())[selectindex] elif c == 9: # Tab pred = autocomplete.predict(modules.keys(), inputstring) if pred is not None: inputstring = pred elif c == 21: # Ctrl-U inputstring = "" elif c == 8: # Backspace inputstring = inputstring[:-1] elif 32 <= c <= 126: # Printable inputstring += str(chr(c)) valid = bool(inputstring in modules) # Update select arrow on module list update_cursor(selectindex) # Update user input box update_inputbox(inputstring, valid)
def print_controls(scr: Window, controls: Iterable[Tuple[str, str]]) -> None: """ Prints the controls in the standard format. """ scr.addstr("Controls:", curses.color_pair(0)) maxkeysize = max(map(len, next(zip(*controls)))) for key, action in controls: scr.addstr("\n") scr.addstr("- ".rjust(6)) scr.addstr(key.ljust(maxkeysize + 1), curses.color_pair(3)) scr.addstr(": " + action, curses.color_pair(0)) scr.addstr("\n\n", curses.color_pair(0))
def setup(scr: Window) -> None: """ Standard procedure for window setup. """ scr.clear() # clear the window colors() # set colors
def main(scr: Window): wards.setup(scr) wards.print_modulename(scr, NAME) wards.print_controls(scr, (("ESC", "Quit the module."), ("Q/W/E/R", "Toggle wire options."), ("TAB", "Reset all wire options to NO."))) scr.addstr("Wire Settings:", curses.color_pair(0)) setting_keys = ("Q", "W", "E", "R") setting_labels = ("Has Red coloring", "Has Blue coloring", "Has Star symbol", "Has LED lit") setting_states = [False, False, False, False] setting_yxs = [] for i in range(4): scr.addstr("\n") scr.addstr((setting_keys[i] + " - ").rjust(6)) scr.addstr(setting_labels[i].ljust(18), curses.color_pair(0)) scr.addstr(": ", curses.color_pair(0)) setting_yxs.append(scr.getyx()) scr.addstr("\n\n") scr.addstr("Instruction: ") instruction_yx = scr.getyx() while True: # Show setting states for i in range(4): scr.move(setting_yxs[i][0], setting_yxs[i][1]) scr.clrtoeol() if setting_states[i]: scr.addstr("YES", curses.color_pair(2)) else: scr.addstr("NO", curses.color_pair(1)) # Show instruction scr.move(instruction_yx[0], instruction_yx[1]) scr.clrtoeol() scr.addstr( get_instruction(setting_states[0], setting_states[1], setting_states[2], setting_states[3])) # Get input c = scr.getch() if c == 27: # Esc return elif c == 9: # Tab setting_states = [False, False, False, False] elif c in (81, 113): # Q setting_states[0] = not setting_states[0] elif c in (87, 119): # W setting_states[1] = not setting_states[1] elif c in (69, 101): # E setting_states[2] = not setting_states[2] elif c in (82, 114): # R setting_states[3] = not setting_states[3]
def main(scr: Window): wards.setup(scr) wards.print_modulename(scr, NAME) scr.addstr("This is a dummy module!\n\n", curses.color_pair(0)) scr.addstr("Press any key to exit.", curses.color_pair(3)) scr.getch()