def main(): """Since 1 braille chars can represent 2*4 points we have to scale the board accordingly""" width, height = drawille.getTerminalSize() width, height = int((width*2.0)-2), int((height*4.0)-4) game = GameOfLife(width=width, height=height) def fill_board_randomly(game): def set_cell_randomly(): if randrange(10) > randrange(6, 10): return 1 return 0 for y in range(game.height): for x in range(game.width): game.board[y][x] = set_cell_randomly() fill_board_randomly(game) def frame_coordinates(game): while True: game.evolve_board() s = [] for y in range(game.height): for x in range(game.width): if game.board[y][x] == 1: s.append((x, y)) yield s s = drawille.Canvas() drawille.animate(s, frame_coordinates, 1./5, game)
def main(stdscr): stdscr.nodelay(1) curses.curs_set(0) termSize = getTerminalSize() argsSize = len(sys.argv) WIDTH = min((int(sys.argv[1]) if argsSize > 1 else 64), termSize[0] * 2) HEIGHT = min((int(sys.argv[2]) if argsSize > 2 else 64), termSize[1] * 4) FRAMES = 4 display = Canvas() grid = getGrid(WIDTH, HEIGHT) addPentomino(grid, int(WIDTH / 2), int(HEIGHT / 2)) drawGrid(display, grid, stdscr) time.sleep(1. / FRAMES) while True: grid = updateGrid(grid, WIDTH, HEIGHT) drawGrid(display, grid, stdscr) key = stdscr.getch() if key == ord('q'): break elif key == ord('s'): addPentomino(grid, int(WIDTH / 2), int(HEIGHT / 2)) elif key == curses.KEY_UP: FRAMES += 1 if FRAMES < 60 else 0 elif key == curses.KEY_DOWN: FRAMES -= 1 if FRAMES > 2 else 0 time.sleep(1. / FRAMES)
def while_waiting(self): ''' called periodically when user is not pressing any key ''' # if not self.update_thread: # t = ThreadJob(self.update,self.stop_event,1) # self.update_thread = t # self.update_thread.start() self._logger.info('Updating GUI due to no keyboard interrupt') ''' Earlier a thread job was being used to update the GUI in background but while_waiting is getting called after 10ms (keypress_timeout_default) so no more thread job is required Only issue is that when user is interacting constantly the GUI won't update ''' terminal_width,terminal_height = drawille.getTerminalSize() self._logger.info("Equating terminal sizes, old {0}*{1} vs {2}*{3}".format(PREVIOUS_TERMINAL_WIDTH, PREVIOUS_TERMINAL_HEIGHT, terminal_width, terminal_height )) # In case the terminal size is changed, try resizing the terminal and redrawing ptop if terminal_width != PREVIOUS_TERMINAL_WIDTH or terminal_height != PREVIOUS_TERMINAL_HEIGHT: self._logger.info("Terminal Size changed, updating the GUI") self.window.erase() self.draw() self.update() # In case the terminal size is not changed, don't redraw the GUI, just update the contents else: self.update()
def goldenratio2drawille(goldenratio, n, s, angle): def square(size): for i in range(4): t.forward(size) t.right(goldenratio.angle) # Taken from python turtle library def circle(radius, extent=None, steps=None): fullCircle = 360 if extent is None: extent = fullCircle if steps is None: frac = abs(extent) / fullCircle steps = 1+int(min(11+abs(radius) / 6.0, 59.0)*frac) w = 1.0 * extent / steps w2 = 0.5 * w l = 2.0 * radius * sin(w2*pi/180.0) if radius < 0: l, w, w2 = -l, -w, -w2 t.right(w2) for i in range(steps): t.forward(l) t.right(w) t.left(w2) t = Turtle() size = getTerminalSize()[0] + s t.rotation = goldenratio.angle + angle for i in range(n): square(size) t.forward(size) t.right(goldenratio.angle) t.forward(size) size /= goldenratio.phi t.up() t.move(0, 0) t.down() size = getTerminalSize()[0] + s t.rotation = goldenratio.angle + angle for i in range(n): circle(size, 90) size /= goldenratio.phi return t.frame()
def __main__(stdsrc, argv=None): if argv == None: argv = sys.argv # Initialize putmatrix matrix = None if len(argv) > 1: # load specified file f = open( argv[1], 'r' ) matrix = [ [ bool(int(val)) for val in line.split(',')] for line in f ] else: matrix = [[True for i in range(20)] for j in range(20)] # Get terminal size term_x, term_y = getTerminalSize() # Set rows and columns columns = (term_x-1)*2 rows = (term_y-1)*4 g = GameOfLife(rows,columns) g.draw() c_x = 0 c_y = 0 stdscr.move(c_y,c_x) while True: g.tick() # Draw to curses g.draw() stdscr.move(c_y,c_x) stdscr.refresh() # Catch user input inp = stdscr.getch() if inp != curses.ERR: # Down if inp == 258: c_y = min(c_y + 1, term_y-1) # Up if inp == 259: c_y = max(c_y - 1, 0) # Left if inp == 260: c_x = max(c_x - 1, 0) # Right if inp == 261: c_x = min(c_x + 1, term_x-1) # Put if inp == ord(" "): g.put(matrix, c_x*2, c_y*4) # Quit if inp == 27: break
def complexset2drawille(complexset, n): can = Canvas() w, h = getTerminalSize() w *= 2 h *= 4 for row in range(h): for col in range(w): if complexset.plot(col, row, w, h, n) >= complexset.MAX_ITER: can.set(col, row) return can.frame()
def getDrawing(): global currentfractal, drawing, iteration, size, angle fractal = fractals[currentfractal] if isinstance(fractal, Mandelbrot) or isinstance(fractal, Julia): drawing = complexset2drawille(fractal, iteration) elif isinstance(fractal, Goldenratio): drawing = goldenratio2drawille(fractal, iteration, size, angle) else: drawing = lsystem2drawille(fractal, iteration, size, angle) # Restrict viewport because curses can't handle UTF outside viewport termSize = getTerminalSize() drawing = '\n'.join(map(lambda x: x[:termSize[0] - 1], drawing.split('\n')[:termSize[1] - 1]))
def main(stdscr): curses.init_pair(1, curses.COLOR_YELLOW, curses.COLOR_BLACK) title = 'welcome-component.js' text = 'abc kanapecki what what the heck is this kurdebele lemme go slower' w, h = drawille.getTerminalSize() stdscr.clear() # Title draw_title(stdscr, title, w, h) # Text word_images = convert_text_to_bitmaps(text) # TODO: This... does not throw an error but does not really work word_images = combine_bitmaps(word_images, w) frames = map(lambda im: termglyph.get_frame(im, color=False), word_images) framelines = [] for frame in frames: x, y = get_frame_starting_cords(frame, w, h) frame = fill_frame_to_x(x, frame) framelines.append(FrameLine(frame, y, w, h)) if len(framelines) == 0: return frame_window = [framelines[0]] frame_index = 1 while not len(frame_window) == 0: stdscr.clear() draw_and_advance_frames(stdscr, frame_window) if frame_window[0].is_out(): frame_window.pop(0) if len(frame_window) > 0 and\ frame_window[-1].can_push_next() and frame_index < len(framelines): frame_window.append(framelines[frame_index]) frame_index += 1 stdscr.refresh() # stdscr.getkey() time.sleep(SWIPE_RATE)
def resize_to_fit(im): term_w, term_h = drawille.getTerminalSize() term_w *= drawille.X_SIZE_RATIO term_h *= drawille.Y_SIZE_RATIO im_width, im_height = im.size w_ratio = im_width / term_w h_ratio = im_height / term_h ratio = w_ratio if w_ratio > h_ratio else h_ratio if ratio > 1: new_width = int(im_width // ratio) new_height = int(im_height // ratio) im = im.resize((new_width, new_height)) return im
def create(self): # Draws a form with a widget for states, log messages, and connection status column_height = drawille.getTerminalSize()[::-1][0] self.states_widget = self.add(npyscreen.BoxTitle, name="Internal States ({} received)", max_height=column_height // 3, editable=True) self.messages_widget = self.add( npyscreen.BoxTitle, name="Log Messages", max_height=column_height // 3, editable=True, ) self.connection_text = self.add_widget(npyscreen.TitleText, name=f"Connection Status: ", editable=False)
exit() if __name__ == '__main__': if len(argv) < 2: url = 'http://xkcd.com/' elif argv[1] in ['-h', '--help']: usage() elif argv[1].startswith('http'): url = argv[1] else: url = 'http://xkcd.com/%s/' % argv[1] c = urllib2.urlopen(url).read() img_url = re.findall('http:\/\/imgs.xkcd.com\/comics\/.*\.png', c)[0] i = Image.open(StringIO(urllib2.urlopen(img_url).read())).convert('L') w, h = i.size tw, th = getTerminalSize() tw *= 2 th *= 2 if tw < w: ratio = tw / float(w) w = tw h = int(h * ratio) i = i.resize((w, h), Image.ANTIALIAS) can = Canvas() x = y = 0 try: i_converted = i.tobytes() except AttributeError: i_converted = i.tostring()
#!/usr/bin/env python from time import sleep import ui import curses import drawille import locale import math import sys locale.setlocale(locale.LC_ALL,"") stdscr = curses.initscr() stdscr.refresh() size = drawille.getTerminalSize() width = (size[0]-1) * ui.HORIZONTAL_PIXELS_PER_CHAR height = (size[1]-1) * ui.VERTICAL_PIXELS_PER_CHAR amplitude = ui.Control("amp", 1, 0, 2) frequency = ui.Control("freq", 1.0, 0.1, 8) phase = ui.Control("phase", 0.0, -1, 1) resolution = ui.Control("res", 5, 1, 10) speed = ui.Control("speed", 1, -2, 2) time = 0 controls = [ amplitude, frequency, phase,
def while_waiting(self): # Saves current terminal size to determine whether or not a redraw # of the TUI is necessary curr_width, curr_height = drawille.getTerminalSize() # Serialized data to be received from manticore server serialized = None try: # Attempts to (re)connect to manticore server if not self._connected: self._mcore_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self._logger.info("Connected to manticore server") self._mcore_socket.connect(("127.0.0.1", 1337)) self._connected = True self._socket_list = [self._mcore_socket] # Uses Python select module with timeout 0 to determine whether or not sockets have any data # To be read from or written to to prevent client send/recv operations from blocking. read_sockets, write_sockets, error_sockets = select.select( self._socket_list, self._socket_list, [], 0) # If there are sockets available for reading, deserialize data if len(read_sockets): serialized = self._mcore_socket.recv(1024) self._logger.info("Received serialized of length {}".format( len(serialized))) # If there are sockets available for writing, send an ACK to server if len(write_sockets): self._mcore_socket.send(b"Received states") # Protobuf can't directly determine the type of data being received, so we use the following workaround # We first try to deserialize data as a StateList object and check its .states attribute # Since in practice a StateList must contain at least one state, we know that if len(.states) is 0 # Then the deserialized message can't be a StateList. We then try deserializing into a MessageList object # and check its .messages attribute. If len(.messages) is empty, then we conclude that the data sent # was corrupted or incorrectly serialized. try: m = StateList() m.ParseFromString(serialized) if len(m.states) > 0: self.all_states += format_states(m) self._logger.info("Deserialized StateList") else: m = MessageList() m.ParseFromString(serialized) self.all_messages += format_messages(m) self._logger.info("Deserialized LogMessage") if len(m.messages) == 0: raise TypeError except DecodeError: self._logger.info( "Unable to deserialize message, malformed response") # Detect server disconnect except socket.error: self._connected = False # Handle any other exceptions except: pass self.MainForm.connection_text.value = f"{'Connected' if self._connected else 'Not connected'}" if curr_width != self.prev_width or curr_height != self.prev_height: self._logger.info('Size changed') self.MainForm.erase() self.draw() self.MainForm.DISPLAY() # Updates the list of states and messages to be displayed # Normally appending to the list of values during while_waiting() would work but we have to # Consider the scenario where the user resizes the terminal, in which case # .erase() is called and all widgets lose their previous values upon being redrawn. # So we maintain a separate list of all currently received states and messages (all_states, all_messages) # and reassign Each widget's list of states / messages instead. self.MainForm.states_widget.entry_widget.values = self.all_states self.MainForm.messages_widget.entry_widget.values = self.all_messages self.MainForm.states_widget.name = f"Internal States ({len(self.MainForm.states_widget.values)} received)" self.MainForm.messages_widget.name = f"Log Messages ({len(self.MainForm.messages_widget.values)} received)" self.MainForm.states_widget.display() self.MainForm.messages_widget.display() self.MainForm.connection_text.display()
def draw(self): # Draws the main TUI form with all sub-widgets and allows for user interaction self.MainForm = ManticoreMain(parentApp=self, name="Manticore TUI") self.prev_width, self.prev_height = drawille.getTerminalSize() self.MainForm.edit()