def monitor(env, nodes): # TODO Does this run at the end of a step? beginning? indeterminate? assert len(nodes) % 2 == 0, "Odd number of nodes won't render correctly" sep = curtsies.fmtstr('') cells = { (0, 0): curtsies.fmtstr('▀', fg=display_color(0), bg=display_color(0)), (0, 1): curtsies.fmtstr('▀', fg=display_color(0), bg=display_color(1)), (0, 2): curtsies.fmtstr('▀', fg=display_color(0), bg=display_color(2)), (1, 0): curtsies.fmtstr('▀', fg=display_color(1), bg=display_color(0)), (1, 1): curtsies.fmtstr('▀', fg=display_color(1), bg=display_color(1)), (1, 2): curtsies.fmtstr('▀', fg=display_color(1), bg=display_color(2)), (2, 0): curtsies.fmtstr('▀', fg=display_color(2), bg=display_color(0)), (2, 1): curtsies.fmtstr('▀', fg=display_color(2), bg=display_color(1)), (2, 2): curtsies.fmtstr('▀', fg=display_color(2), bg=display_color(2)), } with curtsies.CursorAwareWindow() as win: chunks = list(chunk(nodes, win.width*2)) vis = curtsies.FSArray(len(chunks), win.width) while True: for i, row in enumerate(chunks): line = [ cells[row[j].color.value, row[j+1].color.value] for j in range(0, len(row), 2) ] line = sep.join(line) vis[i] = line win.render_to_terminal(vis) yield env.timeout(delay=1)
def rerender(self): # Clear the screen, then re-render everything clearscreen = curtsies.FSArray(self.window.height, self.window.width) for idx, l in enumerate(clearscreen): clearscreen[idx] = [' ' * self.window.width] self.window.render_to_terminal(clearscreen) self._redraw()
def _init_buffer(self, window, lines): # extra height so we can scroll off the bottom # fixed width because we don't handle resizes self.line_buffer = curtsies.FSArray(len(lines) + window.height, 256) curlen = len(self.CURSOR) for idx, l in enumerate(self.rendered): msg = curtsies.fmtstr(l) self.line_buffer[idx, curlen:msg.width + curlen] = [msg]
def main(command): pexpect_session = pexpect.spawn(command) with curtsies.FullscreenWindow() as window: while True: a = curtsies.FSArray(window.height, window.width) text = 'pexpect window manager ' + str(window.height) + 'x' + str( window.width) a[0:1, 0:len(text)] = [blue(text)] window.render_to_terminal(a) try: res = pexpect_session.read_nonblocking(timeout=1) except pexpect.EOF: pass
def draw_screen(self, draw_type='default', quick_help=None): if quick_help is None: quick_help = 'Help: (r)otate shutit sessions | re(d)raw screen | (1,2,3,4) zoom pane in/out | (q)uit' assert draw_type in ('default', 'clearscreen', 'zoomed1', 'zoomed2', 'zoomed3', 'zoomed4') # Header header_text = u' <= Shutit' self.screen_arr = curtsies.FSArray(self.wheight, self.wwidth) self.screen_arr[0:1, 0:len(header_text)] = [blue(header_text)] # Footer space = (self.wwidth - len(quick_help)) * ' ' footer_text = space + quick_help if not self.shutit_global.ispy3: footer_text = footer_text.decode('utf-8') self.screen_arr[self.wheight - 1:self.wheight, 0:len(footer_text)] = [invert(blue(footer_text))] if draw_type in ('default', 'zoomed3', 'zoomed4'): # get sessions - for each ShutIt object in shutit_global sessions = list(get_shutit_pexpect_sessions()) # reverse sessions as we're more likely to be interested in later ones. sessions.reverse() # Update the lower_pane_rotate_count so that it doesn't exceed the length of sessions. self.shutit_global.lower_pane_rotate_count = self.shutit_global.lower_pane_rotate_count % len( sessions) sessions = sessions[ -self.shutit_global. lower_pane_rotate_count:] + sessions[:-self.shutit_global. lower_pane_rotate_count] # Truncate logstream if it gets too big. if self.shutit_global.logstream.getvalue( ) > self.shutit_global.logstream_size: self.shutit_global.logstream.truncate( self.shutit_global.logstream_size) if draw_type == 'default': # Draw the sessions. self.do_layout_default() logstream_lines = [] logstream_string_lines_list = self.shutit_global.logstream.getvalue( ).split('\n') for line in logstream_string_lines_list: logstream_lines.append( SessionPaneLine(line, time.time(), 'log')) self.write_out_lines_to_fit_pane(self.top_left_session_pane, logstream_lines, u'Logs') self.write_out_lines_to_fit_pane( self.top_right_session_pane, self.shutit_global.stacktrace_lines_arr, u'Code Context') # Count two sessions count = 0 for shutit_pexpect_session in sessions: count += 1 if count == 2: self.write_out_lines_to_fit_pane( self.bottom_left_session_pane, shutit_pexpect_session.session_output_lines, u'Shutit Session: ' + str(shutit_pexpect_session.pexpect_session_number) + '/' + str(len(sessions))) elif count == 1: self.write_out_lines_to_fit_pane( self.bottom_right_session_pane, shutit_pexpect_session.session_output_lines, u'ShutIt Session: ' + str(shutit_pexpect_session.pexpect_session_number) + '/' + str(len(sessions))) else: break elif draw_type == 'zoomed1': self.do_layout_zoomed(zoom_number=1) logstream_lines = [] logstream_string_lines_list = self.shutit_global.logstream.getvalue( ).split('\n') for line in logstream_string_lines_list: logstream_lines.append( SessionPaneLine(line, time.time(), 'log')) self.write_out_lines_to_fit_pane(self.top_left_session_pane, logstream_lines, u'Logs') elif draw_type == 'zoomed2': self.do_layout_zoomed(zoom_number=2) self.write_out_lines_to_fit_pane( self.top_left_session_pane, self.shutit_global.stacktrace_lines_arr, u'Code Context') elif draw_type == 'zoomed3': self.do_layout_zoomed(zoom_number=3) # Get first session count = 0 for shutit_pexpect_session in sessions: count += 1 if count == 2: self.write_out_lines_to_fit_pane( self.top_left_session_pane, shutit_pexpect_session.session_output_lines, u'Shutit Session: ' + str(shutit_pexpect_session.pexpect_session_number) + '/' + str(len(sessions))) elif count > 2: break elif draw_type == 'zoomed4': self.do_layout_zoomed(zoom_number=4) # Get second session for shutit_pexpect_session in sessions: self.write_out_lines_to_fit_pane( self.top_left_session_pane, shutit_pexpect_session.session_output_lines, u'ShutIt Session: ' + str(shutit_pexpect_session.pexpect_session_number) + '/' + str(len(sessions))) break elif draw_type == 'clearscreen': for y in range(0, self.wheight): line = u' ' * self.wwidth self.screen_arr[y:y + 1, 0:len(line)] = [line] else: assert False, 'Layout not handled: ' + draw_type if self.do_render: self.window.render_to_terminal(self.screen_arr, cursor_pos=(0, 0))
def scan_controls(camera, menu): global imgcount global hdrframe global exprange global energize global forward global scanning menu.pause() delay = mindelay stopscan = th.Event() stopscan.clear() izero = 5 iss = 3 + izero isd = 5 + izero isc = 7 + izero isr = 9 + izero iim = 11 + izero ihd = 13 + izero with ci.FullscreenWindow() as window: with ci.Input() as inputgen: scr = ci.FSArray(window.height, window.width) ilast = window.height scr[izero - 1, 0:window.width - 1] = ci.fsarray([u'_' * window.width]) scr[ilast - 1, 0:window.width - 2] = ci.fsarray([u'_' * window.width]) scr[ilast - 2, 0:window.width - 2] = ci.fsarray([u'_' * window.width]) msg = ci.fmtstr(on_blue(bold(yellow(u'CONTROL INTERFACE')))) center = int((window.width - msg.width) / 2) scr[izero, center:msg.width] = [msg] msgspeed = ci.fmtstr(u'delay: ') scr[iss, 0:msgspeed.width] = [msgspeed] ispeed = msgspeed.width + 1 msgcw = ci.fmtstr(u'direction:') scr[isd, 0:msgcw.width] = [msgcw] icw = msgcw.width + 2 msgfwd = ci.fmtstr('FORWARD ') msgback = ci.fmtstr('BACKWARD') msgamp = ci.fmtstr(u'position:') scr[isc, 0:msgamp.width] = [msgamp] msgampon = ci.fmtstr(bold(green('LOCKED '))) msgampoff = ci.fmtstr(bold(yellow('UNLOCKED'))) msgrun = ci.fmtstr(u'state:') scr[isr, 0:msgrun.width] = [msgrun] msgon = ci.fmtstr(bold(green('SCANNING'))) msgoff = ci.fmtstr(bold(red('STOP '))) msgimg = ci.fmtstr(u'imgcount: ') scr[iim, 0:msgimg.width] = [msgimg] imgstg = ci.fmtstr(str(imgcount).zfill(imglgth)) scr[iim, icw:icw + imgstg.width] = [imgstg] delaylab = ci.fmtstr(on_blue(bold(yellow('delay (s) =')))) delaystg = ci.fmtstr(on_blue(red(bold(' ' + str(int(delay)))))) scr[izero, 0:delaylab.width] = [delaylab] scr[izero, delaylab.width:delaylab.width + delaystg.width + 1] = [delaystg] isolab = ci.fmtstr(on_blue(bold(yellow('iso =')))) if camera.error == 0: isostg = ci.fmtstr( on_blue(red(bold(' ' + str(camera.get_iso()))))) else: isostg = ci.fmtstr(on_blue(red(bold(' ' + 'No Cam')))) scr[izero, window.width - isolab.width - isostg.width:window.width - isostg.width] = [isolab] scr[izero, window.width - isostg.width:window.width] = [isostg] shutlab = ci.fmtstr(on_blue(bold(yellow('exptime =')))) if camera.error == 0: shutstg = ci.fmtstr( on_blue(red(bold(' ' + str(camera.get_exposure_time()))))) else: shutstg = ci.fmtstr(on_blue(red(bold(' ' + 'No Cam')))) icenter = int((window.width + shutlab.width + shutstg.width) / 2) scr[ilast - 2, icenter - shutlab.width - shutstg.width:icenter - shutstg.width] = [shutlab] scr[ilast - 2, icenter - shutstg.width:icenter] = [shutstg] hdrlab = ci.fmtstr(on_blue(bold(yellow('hdrframe =')))) hdrstg = ci.fmtstr(on_blue(red(bold(' ' + str(hdrframe))))) scr[ilast - 2, window.width - hdrlab.width - hdrstg.width:window.width - hdrstg.width] = [hdrlab] scr[ilast - 2, window.width - hdrstg.width:window.width] = [hdrstg] explab = ci.fmtstr(on_blue(bold(yellow('exprange =')))) expstg = ci.fmtstr(on_blue(red(bold(' ' + str(exprange))))) scr[ilast - 2, 0:explab.width] = [explab] scr[ilast - 2, explab.width:explab.width + expstg.width + 1] = [expstg] scanning = False if not scanning: scr[isr, icw:icw + msgoff.width] = [msgoff] else: scr[isr, icw:icw + msgon.width] = [msgon] if forward: scr[isd, icw:icw + msgfwd.width] = [msgfwd] else: scr[isd, icw:icw + msgback.width] = [msgback] if energize: scr[isc, icw:icw + msgampon.width] = [msgampon] else: scr[isc, icw:icw + msgampoff.width] = [msgampoff] #displays initial values window.render_to_terminal(scr) for c in inputgen: if c == '<ESC>': if scanning: stopscan.set() thscan.join(timeout=None) scanning = False break elif c == '<UP>': ispeed = max(ispeed + 1, msgspeed.width + 1) ispeed = min(ispeed, window.width - 1) scr[iss, ispeed:ispeed + 1] = [ci.fmtstr(yellow('|'))] delay = int(mindelay + float(ispeed - msgspeed.width - 1) / float(window.width - msgspeed.width - 2) * (maxdelay - mindelay)) elif c == '<DOWN>': scr[iss, ispeed:ispeed + 1] = [ci.fmtstr(u' ')] ispeed = max(ispeed - 1, msgspeed.width + 1) ispeed = min(ispeed, window.width - 1) delay = int(mindelay + float(ispeed - msgspeed.width - 1) / float(window.width - msgspeed.width - 2) * (maxdelay - mindelay)) elif c == '<RIGHT>': if not scanning: if not forward: forward = True scr[isd, icw:icw + msgfwd.width] = [msgfwd] elif c == '<LEFT>': if not scanning: if forward: forward = False scr[isd, icw:icw + msgback.width] = [msgback] elif c == '<SPACE>': scanning = not (scanning) if scanning: stopscan.clear() thscan = th.Thread(name='scan', target=scan_frames, args=[camera, delay, stopscan]) thscan.start() scr[isr, icw:icw + msgon.width] = [msgon] else: stopscan.set() thscan.join(timeout=None) scr[isr, icw:icw + msgoff.width] = [msgoff] elif c == '<Ctrl-j>': energize = not (energize) if energize: scr[isc, icw:icw + msgampon.width] = [msgampon] else: scr[isc, icw:icw + msgampoff.width] = [msgampoff] else: msghelp = ci.fmtstr( bold( yellow( u'Use enter, arrow keys and space bar for control. Escape to exit' ))) centerhelp = int((window.width - msghelp.width) / 2) scr[ilast - 1, centerhelp:centerhelp + msghelp.width] = [msghelp] #display updated values # delaylab=ci.fmtstr(on_blue(bold(yellow('delay =')))) delaystg = ci.fmtstr(on_blue(red(bold(' ' + str(int(delay)))))) scr[izero, 0:delaylab.width] = [delaylab] scr[izero, delaylab.width:delaylab.width + delaystg.width + 1] = [delaystg] imgstg = ci.fmtstr(str(imgcount).zfill(imglgth)) scr[iim, icw:icw + imgstg.width] = [imgstg] window.render_to_terminal(scr) menu.resume() return