Files
sics/site_ansto/instrument/util/displayscreen.py
2014-05-16 17:23:54 +10:00

151 lines
4.4 KiB
Python

# vim: ts=8 sts=4 sw=4 expandtab
import curses
class CursesStdIO:
"""fake fd to be registered as a reader with the twisted reactor.
Curses classes needing input should extend this"""
def fileno(self):
""" We want to select on FD 0 """
return 0
def doRead(self):
"""called when input is ready"""
def logPrefix(self): return 'CursesClient'
class Screen(CursesStdIO):
def __init__(self, stdscr):
self.timer = 0
self.statusText = "TEST CURSES APP -"
self.searchText = ''
self.stdscr = stdscr
# set screen attributes
self.stdscr.nodelay(1) # this is used to make input calls non-blocking
curses.cbreak()
self.stdscr.keypad(1)
curses.curs_set(0) # no annoying mouse cursor
self.rows, self.cols = self.stdscr.getmaxyx()
self.lines = []
curses.start_color()
# create color pair's 1 and 2
curses.init_pair(1, curses.COLOR_BLACK, curses.COLOR_WHITE)
curses.init_pair(2, curses.COLOR_CYAN, curses.COLOR_BLACK)
self.paintStatus(self.statusText)
self.stdscr.refresh()
def connectionLost(self, reason):
self.close()
def addLine(self, text):
""" add a line to the internal list of lines"""
self.lines.append(text)
while len(self.lines) > 10:
del self.lines[0]
self.redisplayLines()
def redisplayLines(self):
""" method for redisplaying lines
based on internal list of lines """
self.stdscr.clear()
self.paintStatus(self.statusText)
i = 0
index = len(self.lines) - 1
while i < (self.rows - 3) and index >= 0:
self.stdscr.addstr(self.rows - 3 - i, 0, self.lines[index],
curses.color_pair(2))
i = i + 1
index = index - 1
self.stdscr.refresh()
def paintStatus(self, text):
if len(text) > self.cols: raise TextTooLongError
self.stdscr.addstr(self.rows-2,0,text + ' ' * (self.cols-len(text)),
curses.color_pair(1))
# move cursor to input line
self.stdscr.move(self.rows-1, self.cols-1)
def doRead(self):
""" Input is ready! """
curses.noecho()
self.timer = self.timer + 1
c = self.stdscr.getch() # read a character
if c == curses.KEY_BACKSPACE:
print "curses KEY_BACKSPACE"
self.searchText = self.searchText[:-1]
elif c == curses.KEY_ENTER or c == 10:
self.addLine(self.searchText)
# for testing too
try: self.sendLine(self.searchText)
except: pass
self.stdscr.refresh()
self.searchText = ''
elif c == curses.KEY_RESIZE:
print "curses KEY_RESIZE"
self.rows, self.cols = self.stdscr.getmaxyx()
self.redisplayLines()
self.paintStatus(self.statusText)
self.stdscr.refresh()
elif c >= curses.KEY_MIN and c <= curses.KEY_MAX:
return
else:
if len(self.searchText) >= self.cols-2:
return
self.searchText = self.searchText + chr(c)
self.stdscr.addstr(self.rows-1, 0,
self.searchText + (' ' * (
self.cols-len(self.searchText)-2)))
self.stdscr.move(self.rows-1, len(self.searchText))
self.paintStatus(self.statusText + ' %d' % len(self.searchText))
self.stdscr.refresh()
def sendLine(self, txt):
pass
def close(self):
""" clean up """
curses.nocbreak()
self.stdscr.keypad(0)
curses.echo()
curses.endwin()
def device_display():
global stdscr
try:
import datetime
now = datetime.datetime.now()
str = now.date().isoformat() + " " + now.time().isoformat()
stdscr.addstr(12, 25, "Time: %s" % str)
except:
pass
stdscr.refresh()
if __name__ == '__main__':
global stdscr
from twisted.internet.task import LoopingCall
from twisted.internet import reactor
from twisted.python import log
log.startLogging(open("/tmp/displayscreen.log", "w"))
stdscr = curses.initscr()
screen = Screen(stdscr)
lc = LoopingCall(device_display)
lc.start(0.250)
reactor.addReader(screen) # add screen object as a reader to the reactor
reactor.run()