ttgui / console.py

# -*_ coding: utf-8 -*-
# http://gnosis.cx/publish/programming/charming_python_6.html
# TODO: implement ConsoleLib-API with ncurses: http://effbot.org/zone/console-handbook.htm
import sys
import curses

from keymap import keymap


def debug(*args):
    s = " ".join(str(a) for a in args)
    open("/tmp/debug.log", "a").write("%s\n" % s)

    

class Console(object):
    instance = None
    
    def __init__(self):
        if Console.instance:
            raise RuntimeError("Only one console instance allowed")
        Console.instance = self
        sys.excepthook = self.excepthook
        self.window = curses.initscr()
        if curses.has_colors():
            curses.start_color()
        curses.noecho()
        curses.cbreak()    
        #curses.raw() # intercept everything
        # In keypad mode, escape sequences for special keys
        # (like the cursor keys) will be interpreted and
        # a special value like curses.KEY_LEFT will be returned
        #self.window.keypad(1)

        
        # Frame the interface area at fixed VT100 size
        self.screen = self.window.subwin(25, 80, 0, 0)
        #self.screen.box()
        #self.screen.hline(2, 1, curses.ACS_HLINE, 77)
        self.screen.refresh()
    

        
    def excepthook(self, *args):
        self.close()
        sys.__excepthook__(*args)
        sys.exit(1)


    def __del__(self):
        self.close()
        

    def close(self):
        if self.window:
            self.window.keypad(0)
        curses.echo()
        #curses.nocbreak()
        curses.endwin()


    def getchar(self, wait=False):
        if not wait:
            self.screen.nodelay(1)
            while 1:
                try:
                    curses.cbreak()
                    break
                except _curses.error:
                    pass
        return self.screen.getch()
    
    
    def readkeys(self):
        l = []
        while True:
            key = self.getchar()
            if key == -1:
                break
            l.append(chr(key))
        return "".join(l)

        
    
    def refresh(self):
        self.screen.refresh()
    
    
    def text(self, column, line, string, style=curses.A_NORMAL):
        self.screen.addstr(line, column, string, style)


    def page(self):
        self.window.erase()
        

    def gotoxy(self, x, y):
        self.window.move(x, y)

        
    def show_cursor(self):
        curses.curs_set(2)


    def hide_cursor(self):
        curses.curs_set(0)



if __name__=='__main__':
    c = Console()
    c.text(1,1, "hello, world!")
    i = 0
    while True:
        keys = c.readkeys()
        if keys:
            if keys in keymap:
                keys = keymap[keys]
            i += 1
            c.text(i%23, 1, "%r  " % keys)
    c.close()
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.