104 self.stdscr.addch(y, x, ch) |
104 self.stdscr.addch(y, x, ch) |
105 elif isinstance(ch, str) and len(ch) == 1: |
105 elif isinstance(ch, str) and len(ch) == 1: |
106 self.stdscr.addstr(y, x, ch) |
106 self.stdscr.addstr(y, x, ch) |
107 else: |
107 else: |
108 raise TypeError('Integer or one-char string is required.') |
108 raise TypeError('Integer or one-char string is required.') |
109 except curses.error as e: |
109 except curses.error: |
|
110 if x == self.size.w - 1 and y == self.size.h - 1: |
|
111 # Curses putch to lower-right corner gives error because |
|
112 # scrolling is disabled and cursor cannot move to next char. |
|
113 # Let's just ignore that for now. |
|
114 return |
110 self._log.exception('putch(%r, %s, %s) error:' % (ch, x, y)) |
115 self._log.exception('putch(%r, %s, %s) error:' % (ch, x, y)) |
111 |
116 |
112 def draw(self, buffer, x=0, y=0): |
117 def draw(self, buffer, x=0, y=0): |
113 for bufy in range(buffer.size.h): |
118 for bufy in range(buffer.size.h): |
114 for bufx in range(buffer.size.w): |
119 for bufx in range(buffer.size.w): |
198 res.append(KeypressEvent(keyname, c, set())) |
203 res.append(KeypressEvent(keyname, c, set())) |
199 |
204 |
200 return res |
205 return res |
201 |
206 |
202 def _process_mouse(self): |
207 def _process_mouse(self): |
203 out = [] |
208 res = [] |
204 try: |
209 try: |
205 _id, x, y, _z, bstate = curses.getmouse() |
210 _id, x, y, _z, bstate = curses.getmouse() |
206 except curses.error: |
211 except curses.error: |
207 return out |
212 return res |
208 |
213 |
209 pos = Point(x, y) |
214 pos = Point(x, y) |
210 if bstate & curses.REPORT_MOUSE_POSITION: |
215 if bstate & curses.REPORT_MOUSE_POSITION: |
211 if self._mouse_last_pos != pos: |
216 if self._mouse_last_pos != pos: |
212 if self._mouse_last_pos: |
217 if self._mouse_last_pos: |
213 relpos = pos - self._mouse_last_pos |
218 relpos = pos - self._mouse_last_pos |
214 out += [('mousemove', 0, pos, relpos)] |
219 res.append(MouseEvent('mousemove', 0, pos, relpos)) |
215 self._mouse_last_pos = pos |
220 self._mouse_last_pos = pos |
216 |
221 |
217 # we are interested only in changes, not buttons already pressed before event |
222 # We are interested only in changes, not buttons already pressed before event |
218 if self._mouse_last_bstate is not None: |
223 if self._mouse_last_bstate is not None: |
219 old = self._mouse_last_bstate |
224 old = self._mouse_last_bstate |
220 new = bstate |
225 new = bstate |
221 bstate = ~old & new |
226 bstate = ~old & new |
222 self._mouse_last_bstate = new |
227 self._mouse_last_bstate = new |
223 else: |
228 else: |
224 self._mouse_last_bstate = bstate |
229 self._mouse_last_bstate = bstate |
225 |
230 |
226 if bstate & curses.BUTTON1_PRESSED: |
231 if bstate & curses.BUTTON1_PRESSED: |
227 out += [('mousedown', 1, pos)] |
232 res.append(MouseEvent('mousedown', 1, pos)) |
228 if bstate & curses.BUTTON2_PRESSED: |
233 if bstate & curses.BUTTON2_PRESSED: |
229 out += [('mousedown', 2, pos)] |
234 res.append(MouseEvent('mousedown', 2, pos)) |
230 if bstate & curses.BUTTON3_PRESSED: |
235 if bstate & curses.BUTTON3_PRESSED: |
231 out += [('mousedown', 3, pos)] |
236 res.append(MouseEvent('mousedown', 3, pos)) |
232 if bstate & curses.BUTTON1_RELEASED: |
237 if bstate & curses.BUTTON1_RELEASED: |
233 out += [('mouseup', 1, pos)] |
238 res.append(MouseEvent('mouseup', 1, pos)) |
234 if bstate & curses.BUTTON2_RELEASED: |
239 if bstate & curses.BUTTON2_RELEASED: |
235 out += [('mouseup', 2, pos)] |
240 res.append(MouseEvent('mouseup', 2, pos)) |
236 if bstate & curses.BUTTON3_RELEASED: |
241 if bstate & curses.BUTTON3_RELEASED: |
237 out += [('mouseup', 3, pos)] |
242 res.append(MouseEvent('mouseup', 3, pos)) |
238 |
243 |
239 # reset last pos when pressed/released |
244 # Reset last pos when pressed/released |
240 if len(out) > 0 and out[-1][0] in ('mousedown', 'mouseup'): |
245 if len(res) > 0 and res[-1].name in ('mousedown', 'mouseup'): |
241 self._mouse_last_pos = None |
246 self._mouse_last_pos = None |
242 |
247 |
243 return out |
248 return res |
244 |
249 |
245 def _split_keyname_mods(self, keyname): |
250 def _split_keyname_mods(self, keyname): |
246 """Parse keynames in form "shift+tab", return (keyname, mod).""" |
251 """Parse keynames in form "shift+tab", return (keyname, mod).""" |
247 mod_set = set() |
252 mod_set = set() |
248 if '+' in keyname: |
253 if '+' in keyname: |