OLD | NEW |
| (Empty) |
1 """ | |
2 You don't really want to use this module. Try insults.py instead. | |
3 """ | |
4 | |
5 from twisted.internet import protocol | |
6 | |
7 class InsultsClient(protocol.Protocol): | |
8 | |
9 escapeTimeout = 0.2 | |
10 | |
11 def __init__(self): | |
12 self.width = self.height = None | |
13 self.xpos = self.ypos = 0 | |
14 self.commandQueue = [] | |
15 self.inEscape = '' | |
16 | |
17 def setSize(self, width, height): | |
18 call = 0 | |
19 if self.width: | |
20 call = 1 | |
21 self.width = width | |
22 self.height = height | |
23 if call: | |
24 self.windowSizeChanged() | |
25 | |
26 def dataReceived(self, data): | |
27 from twisted.internet import reactor | |
28 for ch in data: | |
29 if ch == '\x1b': | |
30 if self.inEscape: | |
31 self.keyReceived(ch) | |
32 self.inEscape = '' | |
33 else: | |
34 self.inEscape = ch | |
35 self.escapeCall = reactor.callLater(self.escapeTimeout, | |
36 self.endEscape) | |
37 elif ch in 'ABCD' and self.inEscape: | |
38 self.inEscape = '' | |
39 self.escapeCall.cancel() | |
40 if ch == 'A': | |
41 self.keyReceived('<Up>') | |
42 elif ch == 'B': | |
43 self.keyReceived('<Down>') | |
44 elif ch == 'C': | |
45 self.keyReceived('<Right>') | |
46 elif ch == 'D': | |
47 self.keyReceived('<Left>') | |
48 elif self.inEscape: | |
49 self.inEscape += ch | |
50 else: | |
51 self.keyReceived(ch) | |
52 | |
53 def endEscape(self): | |
54 ch = self.inEscape | |
55 self.inEscape = '' | |
56 self.keyReceived(ch) | |
57 | |
58 def initScreen(self): | |
59 self.transport.write('\x1b=\x1b[?1h') | |
60 | |
61 def gotoXY(self, x, y): | |
62 """Go to a position on the screen. | |
63 """ | |
64 self.xpos = x | |
65 self.ypos = y | |
66 self.commandQueue.append(('gotoxy', x, y)) | |
67 | |
68 def writeCh(self, ch): | |
69 """Write a character to the screen. If we're at the end of the row, | |
70 ignore the write. | |
71 """ | |
72 if self.xpos < self.width - 1: | |
73 self.commandQueue.append(('write', ch)) | |
74 self.xpos += 1 | |
75 | |
76 def writeStr(self, s): | |
77 """Write a string to the screen. This does not wrap a the edge of the | |
78 screen, and stops at \\r and \\n. | |
79 """ | |
80 s = s[:self.width-self.xpos] | |
81 if '\n' in s: | |
82 s=s[:s.find('\n')] | |
83 if '\r' in s: | |
84 s=s[:s.find('\r')] | |
85 self.commandQueue.append(('write', s)) | |
86 self.xpos += len(s) | |
87 | |
88 def eraseToLine(self): | |
89 """Erase from the current position to the end of the line. | |
90 """ | |
91 self.commandQueue.append(('eraseeol',)) | |
92 | |
93 def eraseToScreen(self): | |
94 """Erase from the current position to the end of the screen. | |
95 """ | |
96 self.commandQueue.append(('eraseeos',)) | |
97 | |
98 def clearScreen(self): | |
99 """Clear the screen, and return the cursor to 0, 0. | |
100 """ | |
101 self.commandQueue = [('cls',)] | |
102 self.xpos = self.ypos = 0 | |
103 | |
104 def setAttributes(self, *attrs): | |
105 """Set the attributes for drawing on the screen. | |
106 """ | |
107 self.commandQueue.append(('attributes', attrs)) | |
108 | |
109 def refresh(self): | |
110 """Redraw the screen. | |
111 """ | |
112 redraw = '' | |
113 for command in self.commandQueue: | |
114 if command[0] == 'gotoxy': | |
115 redraw += '\x1b[%i;%iH' % (command[2]+1, command[1]+1) | |
116 elif command[0] == 'write': | |
117 redraw += command[1] | |
118 elif command[0] == 'eraseeol': | |
119 redraw += '\x1b[0K' | |
120 elif command[0] == 'eraseeos': | |
121 redraw += '\x1b[OJ' | |
122 elif command[0] == 'cls': | |
123 redraw += '\x1b[H\x1b[J' | |
124 elif command[0] == 'attributes': | |
125 redraw += '\x1b[%sm' % ';'.join(map(str, command[1])) | |
126 else: | |
127 print command | |
128 self.commandQueue = [] | |
129 self.transport.write(redraw) | |
130 | |
131 def windowSizeChanged(self): | |
132 """Called when the size of the window changes. | |
133 Might want to redraw the screen here, or something. | |
134 """ | |
135 | |
136 def keyReceived(self, key): | |
137 """Called when the user hits a key. | |
138 """ | |
OLD | NEW |