tuikit/driver/curses.py
author Radek Brich <radek.brich@devl.cz>
Fri, 28 Mar 2014 19:58:59 +0100
changeset 97 0c2e0c09ba5c
parent 95 05392e369ede
child 106 abcadb7e2ef1
child 109 105b1affc3c2
permissions -rw-r--r--
Add TextField widget, keypress event, cursor.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
     1
import curses.ascii
57
911927edbdde DriverSDL: Add support for timeouts.
Radek Brich <radek.brich@devl.cz>
parents: 46
diff changeset
     2
import math
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
     3
import logging
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
     4
83
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
     5
from tuikit.driver.driver import Driver
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
     6
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
     7
83
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
     8
class CursesDriver(Driver):
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
     9
65
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
    10
    key_codes = (
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    11
        (0x09,                      'tab'           ),
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    12
        (0x0a,                      'enter'         ),
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    13
        (0x7f,                      'backspace'     ),
4
d197ca00496f Add escape sequences for linux console.
Radek Brich <radek.brich@devl.cz>
parents: 3
diff changeset
    14
        (0x1b,                      'escape'        ),
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    15
        (0x1b, 0x4f, 0x50,          'f1'            ),  # xterm
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    16
        (0x1b, 0x4f, 0x51,          'f2'            ),  # xterm
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    17
        (0x1b, 0x4f, 0x52,          'f3'            ),  # xterm
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    18
        (0x1b, 0x4f, 0x53,          'f4'            ),  # xterm
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    19
        (0x1b, 0x5b,                'CSI'           ),  # see csi_codes
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    20
        (0x1b, 0x5b, 0x4d,          'mouse'         ),
65
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
    21
    )
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
    22
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
    23
    # http://en.wikipedia.org/wiki/ANSI_escape_code
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
    24
    csi_codes = (
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
    25
        # code            param     key name
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
    26
        (0x7e,              1,      'home'          ),  # linux
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
    27
        (0x7e,              2,      'insert'        ),
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
    28
        (0x7e,              3,      'delete'        ),
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
    29
        (0x7e,              4,      'end'           ),  # linux
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
    30
        (0x7e,              5,      'pageup'        ),
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
    31
        (0x7e,              6,      'pagedown'      ),
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
    32
        (0x7e,              15,     'f5'            ),
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
    33
        (0x7e,              17,     'f6'            ),
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
    34
        (0x7e,              18,     'f7'            ),
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
    35
        (0x7e,              19,     'f8'            ),
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
    36
        (0x7e,              20,     'f9'            ),
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
    37
        (0x7e,              21,     'f10'           ),
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
    38
        (0x7e,              23,     'f11'           ),
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
    39
        (0x7e,              24,     'f12'           ),
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
    40
        (0x41,              1,      'up'            ),
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
    41
        (0x42,              1,      'down'          ),
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
    42
        (0x43,              1,      'right'         ),
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
    43
        (0x44,              1,      'left'          ),
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
    44
        (0x46,              1,      'end'           ),  # xterm
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
    45
        (0x48,              1,      'home'          ),  # xterm
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    46
        (0x5b, 0x41,        1,      'f1'            ),  # linux
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    47
        (0x5b, 0x42,        1,      'f2'            ),  # linux
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    48
        (0x5b, 0x43,        1,      'f3'            ),  # linux
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    49
        (0x5b, 0x44,        1,      'f4'            ),  # linux
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    50
        (0x5b, 0x45,        1,      'f5'            ),  # linux
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    51
    )
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    52
27
139d1241b4c5 DriverPygame: add colors, make window resizable.
Radek Brich <radek.brich@devl.cz>
parents: 26
diff changeset
    53
    color_map = {
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    54
        'default':      (-1,                    0),
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    55
        'black':        (curses.COLOR_BLACK,    0),
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    56
        'blue':         (curses.COLOR_BLUE,     0),
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    57
        'green':        (curses.COLOR_GREEN,    0),
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    58
        'cyan':         (curses.COLOR_CYAN,     0),
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    59
        'red':          (curses.COLOR_RED,      0),
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    60
        'magenta':      (curses.COLOR_MAGENTA,  0),
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    61
        'brown':        (curses.COLOR_YELLOW,   0),
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    62
        'lightgray':    (curses.COLOR_WHITE,    0),
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    63
        'gray':         (curses.COLOR_BLACK,    curses.A_BOLD),
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    64
        'lightblue':    (curses.COLOR_BLUE,     curses.A_BOLD),
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    65
        'lightgreen':   (curses.COLOR_GREEN,    curses.A_BOLD),
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    66
        'lightcyan':    (curses.COLOR_CYAN,     curses.A_BOLD),
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    67
        'lightred':     (curses.COLOR_RED,      curses.A_BOLD),
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    68
        'lightmagenta': (curses.COLOR_MAGENTA,  curses.A_BOLD),
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    69
        'yellow':       (curses.COLOR_YELLOW,   curses.A_BOLD),
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    70
        'white':        (curses.COLOR_WHITE,    curses.A_BOLD),
7
d4a291b31cbb New color management - named colors.
Radek Brich <radek.brich@devl.cz>
parents: 5
diff changeset
    71
    }
d4a291b31cbb New color management - named colors.
Radek Brich <radek.brich@devl.cz>
parents: 5
diff changeset
    72
27
139d1241b4c5 DriverPygame: add colors, make window resizable.
Radek Brich <radek.brich@devl.cz>
parents: 26
diff changeset
    73
    attr_map = {
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    74
        'bold':         curses.A_BOLD,
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    75
        'underline':    curses.A_UNDERLINE,
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    76
        'standout':     curses.A_STANDOUT,  # inverse bg/fg
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    77
        'blink':        curses.A_BLINK,
27
139d1241b4c5 DriverPygame: add colors, make window resizable.
Radek Brich <radek.brich@devl.cz>
parents: 26
diff changeset
    78
    }
139d1241b4c5 DriverPygame: add colors, make window resizable.
Radek Brich <radek.brich@devl.cz>
parents: 26
diff changeset
    79
23
4e72fd2a0e14 Rename BackendCurses to DriverCurses. Add DriverDummy - dummy driver for debugging purposes. Move clipping stack from driver to common.ClipStack class.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
    80
    def __init__(self):
24
b248ef500557 Add DriverPygame (incomplete). Move unicode graphics constants to UnicodeGraphics class. Move shared parts of drivers to Driver base class.
Radek Brich <radek.brich@devl.cz>
parents: 23
diff changeset
    81
        Driver.__init__(self)
95
05392e369ede Refactoring: Swap drawing operations parameters. Coords are now last and have default values.
Radek Brich <radek.brich@devl.cz>
parents: 91
diff changeset
    82
        self._log = logging.getLogger('tuikit')
83
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
    83
        self.stdscr = None
5
ae128c885d0f New GridLayout. Change cursor behavior (hide on unfocus event). Change resize event to propagate through containers. Change container clipping - allowlayout=false children are clipped without borders. More Widget doc.
Radek Brich <radek.brich@devl.cz>
parents: 4
diff changeset
    84
        self.cursor = None
7
d4a291b31cbb New color management - named colors.
Radek Brich <radek.brich@devl.cz>
parents: 5
diff changeset
    85
        self.colors = {}     # maps names to curses attributes
d4a291b31cbb New color management - named colors.
Radek Brich <radek.brich@devl.cz>
parents: 5
diff changeset
    86
        self.colorpairs = {} # maps tuple (fg,bg) to curses color_pair
d4a291b31cbb New color management - named colors.
Radek Brich <radek.brich@devl.cz>
parents: 5
diff changeset
    87
        self.colorstack = [] # pushcolor/popcolor puts or gets attributes from this
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    88
        self.inputqueue = []
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    89
        self.mbtnstack = []
68
bc51b0220be2 DriverCurses: filter mousemove - generate event only when coordinates changes.
Radek Brich <radek.brich@devl.cz>
parents: 66
diff changeset
    90
        self._mouse_last_pos = (None, None)
bc51b0220be2 DriverCurses: filter mousemove - generate event only when coordinates changes.
Radek Brich <radek.brich@devl.cz>
parents: 66
diff changeset
    91
        self._mouse_last_bstate = None
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    92
83
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
    93
    ## initialization, finalization ##
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
    94
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
    95
    def init(self):
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
    96
        """Initialize curses"""
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
    97
        self.stdscr = curses.initscr()
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
    98
        curses.start_color()
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
    99
        curses.use_default_colors()
83
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
   100
        curses.noecho()
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
   101
        curses.cbreak()
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
   102
        self.stdscr.keypad(0)
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
   103
        self.stdscr.immedok(0)
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
   104
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
   105
        self.size.h, self.size.w = self.stdscr.getmaxyx()
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
   106
23
4e72fd2a0e14 Rename BackendCurses to DriverCurses. Add DriverDummy - dummy driver for debugging purposes. Move clipping stack from driver to common.ClipStack class.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   107
        curses.curs_set(False)  # hide cursor
4e72fd2a0e14 Rename BackendCurses to DriverCurses. Add DriverDummy - dummy driver for debugging purposes. Move clipping stack from driver to common.ClipStack class.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   108
        curses.mousemask(curses.ALL_MOUSE_EVENTS | curses.REPORT_MOUSE_POSITION)
4e72fd2a0e14 Rename BackendCurses to DriverCurses. Add DriverDummy - dummy driver for debugging purposes. Move clipping stack from driver to common.ClipStack class.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   109
        curses.mouseinterval(0)  # do not wait to detect clicks, we use only press/release
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   110
83
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
   111
    def close(self):
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
   112
        self.stdscr.keypad(0)
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
   113
        curses.echo()
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
   114
        curses.nocbreak()
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
   115
        curses.endwin()
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
   116
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
   117
    ## drawing ##
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
   118
91
de80e140b0ec Add clipping for Buffer draw operations.
Radek Brich <radek.brich@devl.cz>
parents: 88
diff changeset
   119
    def clear(self):
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   120
        self.stdscr.erase()
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   121
95
05392e369ede Refactoring: Swap drawing operations parameters. Coords are now last and have default values.
Radek Brich <radek.brich@devl.cz>
parents: 91
diff changeset
   122
    def putch(self, ch, x, y):
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   123
        try:
95
05392e369ede Refactoring: Swap drawing operations parameters. Coords are now last and have default values.
Radek Brich <radek.brich@devl.cz>
parents: 91
diff changeset
   124
            if isinstance(ch, int):
05392e369ede Refactoring: Swap drawing operations parameters. Coords are now last and have default values.
Radek Brich <radek.brich@devl.cz>
parents: 91
diff changeset
   125
                self.stdscr.addch(y, x, ch)
05392e369ede Refactoring: Swap drawing operations parameters. Coords are now last and have default values.
Radek Brich <radek.brich@devl.cz>
parents: 91
diff changeset
   126
            elif isinstance(ch, str) and len(ch) == 1:
86
0978fb755d31 Add core Application (adjusted), Window (new version), Signal (replaces Emitter), Size (adjusted). Add application demo.
Radek Brich <radek.brich@devl.cz>
parents: 84
diff changeset
   127
                self.stdscr.addstr(y, x, ch)
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   128
            else:
95
05392e369ede Refactoring: Swap drawing operations parameters. Coords are now last and have default values.
Radek Brich <radek.brich@devl.cz>
parents: 91
diff changeset
   129
                raise TypeError('Integer or one-char string is required.')
05392e369ede Refactoring: Swap drawing operations parameters. Coords are now last and have default values.
Radek Brich <radek.brich@devl.cz>
parents: 91
diff changeset
   130
        except curses.error as e:
05392e369ede Refactoring: Swap drawing operations parameters. Coords are now last and have default values.
Radek Brich <radek.brich@devl.cz>
parents: 91
diff changeset
   131
            self._log.exception('putch(%r, %s, %s) error:' % (ch, x, y))
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   132
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   133
    def draw(self, buffer, x=0, y=0):
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   134
        for bufy in range(buffer.size.h):
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   135
            for bufx in range(buffer.size.w):
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   136
                char, attr_desc = buffer.get(bufx, bufy)
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   137
                self.setattr(attr_desc)
95
05392e369ede Refactoring: Swap drawing operations parameters. Coords are now last and have default values.
Radek Brich <radek.brich@devl.cz>
parents: 91
diff changeset
   138
                self.putch(char, x + bufx, y + bufy)
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   139
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   140
    def flush(self):
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   141
        if self.cursor:
97
0c2e0c09ba5c Add TextField widget, keypress event, cursor.
Radek Brich <radek.brich@devl.cz>
parents: 95
diff changeset
   142
            self.stdscr.move(self.cursor.y, self.cursor.x)
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   143
            curses.curs_set(True)
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   144
        else:
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   145
            curses.curs_set(False)
83
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
   146
        self.stdscr.refresh()
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   147
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   148
    ## colors, attributes ##
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   149
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   150
    def setattr(self, attr_desc):
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   151
        """Set attribute to be used for subsequent draw operations."""
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   152
        attr = self.colors.get(attr_desc, None)
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   153
        if attr is None:
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   154
            # first encountered `attr_desc`, initialize
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   155
            fg, bg, attrs = self._parse_attr_desc(attr_desc)
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   156
            fgcol, fgattr = self.color_map[fg]
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   157
            bgcol, _bgattr = self.color_map[bg]
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   158
            colpair = self._getcolorpair(fgcol, bgcol)
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   159
            attr = curses.color_pair(colpair) | self._parseattrs(attrs) | fgattr
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   160
            self.colors[attr_desc] = attr
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   161
        self.stdscr.attrset(attr)
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   162
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   163
    def _getcolorpair(self, fgcol, bgcol):
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   164
        pair = (fgcol, bgcol)
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   165
        if pair in self.colorpairs:
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   166
            return self.colorpairs[pair]
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   167
        num = len(self.colorpairs) + 1
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   168
        curses.init_pair(num, fgcol, bgcol)
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   169
        self.colorpairs[pair] = num
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   170
        return num
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   171
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   172
    def _parseattrs(self, attrs):
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   173
        res = 0
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   174
        for a in attrs:
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   175
            res = res | self.attr_map[a]
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   176
        return res
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   177
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   178
    ## input, events ##
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   179
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   180
    def getevents(self, timeout=None):
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   181
        """Process input, return list of events.
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   182
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   183
        timeout -- float, in seconds (None=infinite)
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   184
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   185
        Returns:
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   186
            [('event', param1, ...), ...]
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   187
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   188
        """
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   189
        # empty queue -> fill
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   190
        if len(self.inputqueue) == 0:
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   191
            if timeout is not None:
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   192
                timeout = math.ceil(timeout * 10)
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   193
            self._inputqueue_fill(timeout)
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   194
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   195
        res = []
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   196
        while len(self.inputqueue):
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   197
            c = self._inputqueue_get()
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   198
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   199
            if c == curses.KEY_MOUSE:
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   200
                res += self._process_mouse()
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   201
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   202
            elif c == curses.KEY_RESIZE:
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   203
                self.size.h, self.size.w = self.stdscr.getmaxyx()
88
90d00354dc70 Add WindowManager, basic event handling.
Radek Brich <radek.brich@devl.cz>
parents: 86
diff changeset
   204
                res.append(('resize', self.size.w, self.size.h))
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   205
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   206
            elif curses.ascii.isctrl(c):
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   207
                self._inputqueue_unget(c)
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   208
                res += self._process_control_chars()
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   209
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   210
            elif 192 <= c <= 255:
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   211
                self._inputqueue_unget(c)
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   212
                res += self._process_utf8_chars()
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   213
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   214
            elif curses.ascii.isprint(c):
97
0c2e0c09ba5c Add TextField widget, keypress event, cursor.
Radek Brich <radek.brich@devl.cz>
parents: 95
diff changeset
   215
                res += [('keypress', None, str(chr(c)), set())]
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   216
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   217
            else:
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   218
                self._inputqueue_unget(c)
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   219
                res += self._process_control_chars()
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   220
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   221
        return res
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   222
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   223
    def _inputqueue_fill(self, timeout=None):
57
911927edbdde DriverSDL: Add support for timeouts.
Radek Brich <radek.brich@devl.cz>
parents: 46
diff changeset
   224
        """Wait for curses input, add it to inputqueue.
911927edbdde DriverSDL: Add support for timeouts.
Radek Brich <radek.brich@devl.cz>
parents: 46
diff changeset
   225
911927edbdde DriverSDL: Add support for timeouts.
Radek Brich <radek.brich@devl.cz>
parents: 46
diff changeset
   226
        timeout -- int, tenths of second (None=infinite)
911927edbdde DriverSDL: Add support for timeouts.
Radek Brich <radek.brich@devl.cz>
parents: 46
diff changeset
   227
911927edbdde DriverSDL: Add support for timeouts.
Radek Brich <radek.brich@devl.cz>
parents: 46
diff changeset
   228
        """
3
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   229
        if timeout is None:
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   230
            # wait indefinitely
83
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
   231
            c = self.stdscr.getch()
3
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   232
            self.inputqueue.insert(0, c)
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   233
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   234
        elif timeout > 0:
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   235
            # wait
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   236
            curses.halfdelay(timeout)
83
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
   237
            c = self.stdscr.getch()
3
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   238
            curses.cbreak()
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   239
            if c == -1:
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   240
                return
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   241
            self.inputqueue.insert(0, c)
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   242
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   243
        # timeout = 0 -> no wait
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   244
83
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
   245
        self.stdscr.nodelay(1)
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   246
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   247
        while True:
83
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
   248
            c = self.stdscr.getch()
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   249
            if c == -1:
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   250
                break
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   251
            self.inputqueue.insert(0, c)
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   252
83
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
   253
        self.stdscr.nodelay(0)
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   254
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   255
    def _inputqueue_get(self):
3
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   256
        c = None
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   257
        try:
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   258
            c = self.inputqueue.pop()
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   259
        except IndexError:
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   260
            pass
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   261
        return c
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   262
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   263
    def _inputqueue_get_wait(self):
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   264
        c = None
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   265
        while c is None:
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   266
            try:
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   267
                c = self.inputqueue.pop()
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   268
            except IndexError:
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   269
                curses.napms(25)
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   270
                self._inputqueue_fill(0)
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   271
        return c
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   272
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   273
    def _inputqueue_unget(self, c):
3
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   274
        self.inputqueue.append(c)
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   275
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   276
    def _process_mouse(self):
4
d197ca00496f Add escape sequences for linux console.
Radek Brich <radek.brich@devl.cz>
parents: 3
diff changeset
   277
        try:
25
f69a1f0382ce Partial DriverPygame.putch() implementation. Add patch for PyGame implementing font.render_glyph(). Add test for PyGame font module. Add special key definitions to DriverPygame.
Radek Brich <radek.brich@devl.cz>
parents: 24
diff changeset
   278
            _id, x, y, _z, bstate = curses.getmouse()
4
d197ca00496f Add escape sequences for linux console.
Radek Brich <radek.brich@devl.cz>
parents: 3
diff changeset
   279
        except curses.error:
d197ca00496f Add escape sequences for linux console.
Radek Brich <radek.brich@devl.cz>
parents: 3
diff changeset
   280
            return []
d197ca00496f Add escape sequences for linux console.
Radek Brich <radek.brich@devl.cz>
parents: 3
diff changeset
   281
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   282
        out = []
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   283
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   284
        if bstate & curses.REPORT_MOUSE_POSITION:
68
bc51b0220be2 DriverCurses: filter mousemove - generate event only when coordinates changes.
Radek Brich <radek.brich@devl.cz>
parents: 66
diff changeset
   285
            if self._mouse_last_pos != (x, y):
71
cfd3445107b4 Report mousemove relative position change. Window: when in AnchorLayout, aligned right/bottom - fix resizing by mouse to behave as expected.
Radek Brich <radek.brich@devl.cz>
parents: 70
diff changeset
   286
                if self._mouse_last_pos[0] is not None:
cfd3445107b4 Report mousemove relative position change. Window: when in AnchorLayout, aligned right/bottom - fix resizing by mouse to behave as expected.
Radek Brich <radek.brich@devl.cz>
parents: 70
diff changeset
   287
                    relx = x - (self._mouse_last_pos[0] or 0)
cfd3445107b4 Report mousemove relative position change. Window: when in AnchorLayout, aligned right/bottom - fix resizing by mouse to behave as expected.
Radek Brich <radek.brich@devl.cz>
parents: 70
diff changeset
   288
                    rely = y - (self._mouse_last_pos[1] or 0)
cfd3445107b4 Report mousemove relative position change. Window: when in AnchorLayout, aligned right/bottom - fix resizing by mouse to behave as expected.
Radek Brich <radek.brich@devl.cz>
parents: 70
diff changeset
   289
                    out += [('mousemove', 0, x, y, relx, rely)]
68
bc51b0220be2 DriverCurses: filter mousemove - generate event only when coordinates changes.
Radek Brich <radek.brich@devl.cz>
parents: 66
diff changeset
   290
                self._mouse_last_pos = (x, y)
bc51b0220be2 DriverCurses: filter mousemove - generate event only when coordinates changes.
Radek Brich <radek.brich@devl.cz>
parents: 66
diff changeset
   291
bc51b0220be2 DriverCurses: filter mousemove - generate event only when coordinates changes.
Radek Brich <radek.brich@devl.cz>
parents: 66
diff changeset
   292
        # we are interested only in changes, not buttons already pressed before event
bc51b0220be2 DriverCurses: filter mousemove - generate event only when coordinates changes.
Radek Brich <radek.brich@devl.cz>
parents: 66
diff changeset
   293
        if self._mouse_last_bstate is not None:
bc51b0220be2 DriverCurses: filter mousemove - generate event only when coordinates changes.
Radek Brich <radek.brich@devl.cz>
parents: 66
diff changeset
   294
            old = self._mouse_last_bstate
bc51b0220be2 DriverCurses: filter mousemove - generate event only when coordinates changes.
Radek Brich <radek.brich@devl.cz>
parents: 66
diff changeset
   295
            new = bstate
bc51b0220be2 DriverCurses: filter mousemove - generate event only when coordinates changes.
Radek Brich <radek.brich@devl.cz>
parents: 66
diff changeset
   296
            bstate = ~old & new
bc51b0220be2 DriverCurses: filter mousemove - generate event only when coordinates changes.
Radek Brich <radek.brich@devl.cz>
parents: 66
diff changeset
   297
            self._mouse_last_bstate = new
bc51b0220be2 DriverCurses: filter mousemove - generate event only when coordinates changes.
Radek Brich <radek.brich@devl.cz>
parents: 66
diff changeset
   298
        else:
bc51b0220be2 DriverCurses: filter mousemove - generate event only when coordinates changes.
Radek Brich <radek.brich@devl.cz>
parents: 66
diff changeset
   299
            self._mouse_last_bstate = bstate
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   300
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   301
        if bstate & curses.BUTTON1_PRESSED:
71
cfd3445107b4 Report mousemove relative position change. Window: when in AnchorLayout, aligned right/bottom - fix resizing by mouse to behave as expected.
Radek Brich <radek.brich@devl.cz>
parents: 70
diff changeset
   302
            out += [('mousedown', 1, x, y)]
68
bc51b0220be2 DriverCurses: filter mousemove - generate event only when coordinates changes.
Radek Brich <radek.brich@devl.cz>
parents: 66
diff changeset
   303
        if bstate & curses.BUTTON2_PRESSED:
71
cfd3445107b4 Report mousemove relative position change. Window: when in AnchorLayout, aligned right/bottom - fix resizing by mouse to behave as expected.
Radek Brich <radek.brich@devl.cz>
parents: 70
diff changeset
   304
            out += [('mousedown', 2, x, y)]
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   305
        if bstate & curses.BUTTON3_PRESSED:
71
cfd3445107b4 Report mousemove relative position change. Window: when in AnchorLayout, aligned right/bottom - fix resizing by mouse to behave as expected.
Radek Brich <radek.brich@devl.cz>
parents: 70
diff changeset
   306
            out += [('mousedown', 3, x, y)]
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   307
        if bstate & curses.BUTTON1_RELEASED:
71
cfd3445107b4 Report mousemove relative position change. Window: when in AnchorLayout, aligned right/bottom - fix resizing by mouse to behave as expected.
Radek Brich <radek.brich@devl.cz>
parents: 70
diff changeset
   308
            out += [('mouseup', 1, x, y)]
68
bc51b0220be2 DriverCurses: filter mousemove - generate event only when coordinates changes.
Radek Brich <radek.brich@devl.cz>
parents: 66
diff changeset
   309
        if bstate & curses.BUTTON2_RELEASED:
71
cfd3445107b4 Report mousemove relative position change. Window: when in AnchorLayout, aligned right/bottom - fix resizing by mouse to behave as expected.
Radek Brich <radek.brich@devl.cz>
parents: 70
diff changeset
   310
            out += [('mouseup', 2, x, y)]
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   311
        if bstate & curses.BUTTON3_RELEASED:
71
cfd3445107b4 Report mousemove relative position change. Window: when in AnchorLayout, aligned right/bottom - fix resizing by mouse to behave as expected.
Radek Brich <radek.brich@devl.cz>
parents: 70
diff changeset
   312
            out += [('mouseup', 3, x, y)]
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   313
68
bc51b0220be2 DriverCurses: filter mousemove - generate event only when coordinates changes.
Radek Brich <radek.brich@devl.cz>
parents: 66
diff changeset
   314
        # reset last pos when pressed/released
bc51b0220be2 DriverCurses: filter mousemove - generate event only when coordinates changes.
Radek Brich <radek.brich@devl.cz>
parents: 66
diff changeset
   315
        if len(out) > 0 and out[-1][0] in ('mousedown', 'mouseup'):
bc51b0220be2 DriverCurses: filter mousemove - generate event only when coordinates changes.
Radek Brich <radek.brich@devl.cz>
parents: 66
diff changeset
   316
            self._mouse_last_pos = (None, None)
bc51b0220be2 DriverCurses: filter mousemove - generate event only when coordinates changes.
Radek Brich <radek.brich@devl.cz>
parents: 66
diff changeset
   317
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   318
        return out
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   319
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   320
    def _process_utf8_chars(self):
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   321
        #FIXME read exact number of chars as defined by utf-8
20
472a753664f9 Update utf8 character input to Python3. Reorganize tests.
Radek Brich <radek.brich@devl.cz>
parents: 18
diff changeset
   322
        utf = []
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   323
        while len(utf) <= 6:
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   324
            c = self._inputqueue_get_wait()
20
472a753664f9 Update utf8 character input to Python3. Reorganize tests.
Radek Brich <radek.brich@devl.cz>
parents: 18
diff changeset
   325
            utf.append(c)
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   326
            try:
20
472a753664f9 Update utf8 character input to Python3. Reorganize tests.
Radek Brich <radek.brich@devl.cz>
parents: 18
diff changeset
   327
                uni = str(bytes(utf), 'utf-8')
97
0c2e0c09ba5c Add TextField widget, keypress event, cursor.
Radek Brich <radek.brich@devl.cz>
parents: 95
diff changeset
   328
                return [('keypress', None, uni, set())]
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   329
            except UnicodeDecodeError:
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   330
                continue
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   331
        raise Exception('Invalid UTF-8 sequence: %r' % utf)
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   332
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   333
    def _process_control_chars(self):
65
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   334
        codes = self.key_codes
3
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   335
        matchingcodes = []
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   336
        match = None
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   337
        consumed = []
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   338
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   339
        # consume next char, filter out matching codes
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   340
        c = self._inputqueue_get_wait()
3
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   341
        consumed.append(c)
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   342
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   343
        while True:
41
37b7dfc3eae6 Update Emitter: All event handlers now have exactly one argument: object inherited from Event class, which carries any data.
Radek Brich <radek.brich@devl.cz>
parents: 34
diff changeset
   344
            #self.log.debug('c=%s len=%s', c, len(codes))
3
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   345
            for code in codes:
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   346
                if c == code[len(consumed)-1]:
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   347
                    if len(code) - 1 == len(consumed):
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   348
                        match = code
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   349
                    else:
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   350
                        matchingcodes += [code]
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   351
41
37b7dfc3eae6 Update Emitter: All event handlers now have exactly one argument: object inherited from Event class, which carries any data.
Radek Brich <radek.brich@devl.cz>
parents: 34
diff changeset
   352
            #self.log.debug('matching=%s', len(matchingcodes))
3
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   353
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   354
            # match found, or no matching code found -> stop
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   355
            if len(matchingcodes) == 0:
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   356
                break
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   357
3
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   358
            # match found and some sequencies still match -> continue
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   359
            if len(matchingcodes) > 0:
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   360
                if len(self.inputqueue) == 0:
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   361
                    self._inputqueue_fill(1)
3
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   362
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   363
            c = self._inputqueue_get()
3
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   364
            if c:
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   365
                consumed.append(c)
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   366
                codes = matchingcodes
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   367
                matchingcodes = []
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   368
            else:
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   369
                break
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   370
3
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   371
        keyname = None
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   372
        if match:
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   373
            # compare match to consumed, return unused chars
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   374
            l = len(match) - 1
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   375
            while len(consumed) > l:
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   376
                self._inputqueue_unget(consumed[-1])
3
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   377
                del consumed[-1]
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   378
            keyname = match[-1]
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   379
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   380
        if match is None:
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   381
            self.log.debug('Unknown control sequence: %s',
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   382
                           ','.join(['0x%x' % x for x in consumed]))
97
0c2e0c09ba5c Add TextField widget, keypress event, cursor.
Radek Brich <radek.brich@devl.cz>
parents: 95
diff changeset
   383
            return [('keypress', 'Unknown', None, set())]
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   384
66
Radek Brich <radek.brich@devl.cz>
parents: 65
diff changeset
   385
        if keyname == 'mouse':
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   386
            return self._process_xterm_mouse()
66
Radek Brich <radek.brich@devl.cz>
parents: 65
diff changeset
   387
65
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   388
        if keyname == 'CSI':
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   389
            return self._process_control_sequence()
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   390
97
0c2e0c09ba5c Add TextField widget, keypress event, cursor.
Radek Brich <radek.brich@devl.cz>
parents: 95
diff changeset
   391
        return [('keypress', keyname, None, set())]
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   392
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   393
    def _process_xterm_mouse(self):
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   394
        t = self._inputqueue_get_wait()
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   395
        x = self._inputqueue_get_wait() - 0x21
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   396
        y = self._inputqueue_get_wait() - 0x21
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   397
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   398
        out = []
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   399
71
cfd3445107b4 Report mousemove relative position change. Window: when in AnchorLayout, aligned right/bottom - fix resizing by mouse to behave as expected.
Radek Brich <radek.brich@devl.cz>
parents: 70
diff changeset
   400
        if t in (0x20, 0x21, 0x22):
cfd3445107b4 Report mousemove relative position change. Window: when in AnchorLayout, aligned right/bottom - fix resizing by mouse to behave as expected.
Radek Brich <radek.brich@devl.cz>
parents: 70
diff changeset
   401
            # button press
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   402
            btn = t - 0x1f
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   403
            if not btn in self.mbtnstack:
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   404
                self.mbtnstack.append(btn)
68
bc51b0220be2 DriverCurses: filter mousemove - generate event only when coordinates changes.
Radek Brich <radek.brich@devl.cz>
parents: 66
diff changeset
   405
                self._mouse_last_pos = (None, None)
71
cfd3445107b4 Report mousemove relative position change. Window: when in AnchorLayout, aligned right/bottom - fix resizing by mouse to behave as expected.
Radek Brich <radek.brich@devl.cz>
parents: 70
diff changeset
   406
                out += [('mousedown', btn, x, y)]
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   407
            else:
71
cfd3445107b4 Report mousemove relative position change. Window: when in AnchorLayout, aligned right/bottom - fix resizing by mouse to behave as expected.
Radek Brich <radek.brich@devl.cz>
parents: 70
diff changeset
   408
                # mouse move
68
bc51b0220be2 DriverCurses: filter mousemove - generate event only when coordinates changes.
Radek Brich <radek.brich@devl.cz>
parents: 66
diff changeset
   409
                if self._mouse_last_pos != (x, y):
71
cfd3445107b4 Report mousemove relative position change. Window: when in AnchorLayout, aligned right/bottom - fix resizing by mouse to behave as expected.
Radek Brich <radek.brich@devl.cz>
parents: 70
diff changeset
   410
                    if self._mouse_last_pos[0] is not None:
cfd3445107b4 Report mousemove relative position change. Window: when in AnchorLayout, aligned right/bottom - fix resizing by mouse to behave as expected.
Radek Brich <radek.brich@devl.cz>
parents: 70
diff changeset
   411
                        relx = x - self._mouse_last_pos[0]
cfd3445107b4 Report mousemove relative position change. Window: when in AnchorLayout, aligned right/bottom - fix resizing by mouse to behave as expected.
Radek Brich <radek.brich@devl.cz>
parents: 70
diff changeset
   412
                        rely = y - self._mouse_last_pos[1]
cfd3445107b4 Report mousemove relative position change. Window: when in AnchorLayout, aligned right/bottom - fix resizing by mouse to behave as expected.
Radek Brich <radek.brich@devl.cz>
parents: 70
diff changeset
   413
                        out += [('mousemove', btn, x, y, relx, rely)]
68
bc51b0220be2 DriverCurses: filter mousemove - generate event only when coordinates changes.
Radek Brich <radek.brich@devl.cz>
parents: 66
diff changeset
   414
                    self._mouse_last_pos = (x, y)
71
cfd3445107b4 Report mousemove relative position change. Window: when in AnchorLayout, aligned right/bottom - fix resizing by mouse to behave as expected.
Radek Brich <radek.brich@devl.cz>
parents: 70
diff changeset
   415
        elif t == 0x23:
cfd3445107b4 Report mousemove relative position change. Window: when in AnchorLayout, aligned right/bottom - fix resizing by mouse to behave as expected.
Radek Brich <radek.brich@devl.cz>
parents: 70
diff changeset
   416
            # button release
41
37b7dfc3eae6 Update Emitter: All event handlers now have exactly one argument: object inherited from Event class, which carries any data.
Radek Brich <radek.brich@devl.cz>
parents: 34
diff changeset
   417
            btn = self.mbtnstack.pop()
68
bc51b0220be2 DriverCurses: filter mousemove - generate event only when coordinates changes.
Radek Brich <radek.brich@devl.cz>
parents: 66
diff changeset
   418
            self._mouse_last_pos = (None, None)
71
cfd3445107b4 Report mousemove relative position change. Window: when in AnchorLayout, aligned right/bottom - fix resizing by mouse to behave as expected.
Radek Brich <radek.brich@devl.cz>
parents: 70
diff changeset
   419
            out += [('mouseup', btn, x, y)]
cfd3445107b4 Report mousemove relative position change. Window: when in AnchorLayout, aligned right/bottom - fix resizing by mouse to behave as expected.
Radek Brich <radek.brich@devl.cz>
parents: 70
diff changeset
   420
        elif t in (0x60, 0x61):
cfd3445107b4 Report mousemove relative position change. Window: when in AnchorLayout, aligned right/bottom - fix resizing by mouse to behave as expected.
Radek Brich <radek.brich@devl.cz>
parents: 70
diff changeset
   421
            # wheel up, down
41
37b7dfc3eae6 Update Emitter: All event handlers now have exactly one argument: object inherited from Event class, which carries any data.
Radek Brich <radek.brich@devl.cz>
parents: 34
diff changeset
   422
            btn = 4 + t - 0x60
71
cfd3445107b4 Report mousemove relative position change. Window: when in AnchorLayout, aligned right/bottom - fix resizing by mouse to behave as expected.
Radek Brich <radek.brich@devl.cz>
parents: 70
diff changeset
   423
            out += [('mousewheel', btn, x, y)]
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   424
        else:
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   425
            raise Exception('Unknown mouse event: %x' % t)
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   426
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   427
        return out
29
c0cdef06fd16 Import only one driver from application.
Radek Brich <radek.brich@devl.cz>
parents: 27
diff changeset
   428
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   429
    def _process_control_sequence(self):
65
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   430
        codes = self.csi_codes
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   431
        debug_seq = [0x1b, 0x5b]
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   432
        c = self._inputqueue_get_wait()
65
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   433
        debug_seq.append(c)
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   434
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   435
        # numeric parameters?
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   436
        params = []
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   437
        if chr(c).isdigit():
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   438
            params.append(chr(c))
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   439
            while True:
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   440
                c = self._inputqueue_get_wait()
65
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   441
                debug_seq.append(c)
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   442
                if chr(c).isdigit():
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   443
                    params[-1] += chr(c)
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   444
                elif chr(c) == ';':
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   445
                    params.append('')
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   446
                else:
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   447
                    break
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   448
        params = [int(x) for x in params]
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   449
        if len(params) == 0:
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   450
            params = [1]
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   451
68
bc51b0220be2 DriverCurses: filter mousemove - generate event only when coordinates changes.
Radek Brich <radek.brich@devl.cz>
parents: 66
diff changeset
   452
        # filter codes using byte sequence
65
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   453
        while True:
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   454
            matching_codes = []
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   455
            for code in codes:
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   456
                if len(code) > 2 and code[0] == c:
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   457
                    matching_codes.append(code[1:])
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   458
            codes = matching_codes
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   459
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   460
            if len(codes) == 0:
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   461
                # no match -> unknown code
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   462
                seq = ','.join(['0x%x' % x for x in debug_seq])
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   463
                self.log.debug('Unknown control sequence: %s', seq)
97
0c2e0c09ba5c Add TextField widget, keypress event, cursor.
Radek Brich <radek.brich@devl.cz>
parents: 95
diff changeset
   464
                return [('keypress', 'Unknown:' + seq, None, set())]
65
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   465
            elif len(codes) == 1:
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   466
                # one match -> we got the winner
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   467
                break
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   468
            elif len(codes[0]) == 2:
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   469
                # more than one matching, but no more chars to check
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   470
                # will be sorted out using parameters
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   471
                break
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   472
            else:
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   473
                # more than one matching -> continue loop
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   474
                c = self._inputqueue_get_wait()
65
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   475
                debug_seq.append(c)
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   476
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   477
        # filter codes using first parameter
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   478
        matching_codes = []
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   479
        for code in codes:
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   480
            if params[0] == code[0] or params[0] is None:
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   481
                matching_codes.append(code)
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   482
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   483
        if len(matching_codes) == 0:
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   484
            # no match -> unknown code
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   485
            seq = ','.join(['0x%x' % x for x in debug_seq])
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   486
            self.log.debug('Unknown control sequence: %s', seq)
97
0c2e0c09ba5c Add TextField widget, keypress event, cursor.
Radek Brich <radek.brich@devl.cz>
parents: 95
diff changeset
   487
            return [('keypress', 'Unknown:' + seq, None, set())]
65
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   488
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   489
        if len(matching_codes) > 1:
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   490
            raise Exception('Internal error: invalid csi_codes, more than one matching')
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   491
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   492
        keyname = matching_codes[0][1]
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   493
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   494
        # modifiers
97
0c2e0c09ba5c Add TextField widget, keypress event, cursor.
Radek Brich <radek.brich@devl.cz>
parents: 95
diff changeset
   495
        mod_bits = 0
65
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   496
        if len(params) > 1:
97
0c2e0c09ba5c Add TextField widget, keypress event, cursor.
Radek Brich <radek.brich@devl.cz>
parents: 95
diff changeset
   497
            mod_bits = params[1] - 1
65
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   498
97
0c2e0c09ba5c Add TextField widget, keypress event, cursor.
Radek Brich <radek.brich@devl.cz>
parents: 95
diff changeset
   499
        # convert modifiers from bit-map to set
0c2e0c09ba5c Add TextField widget, keypress event, cursor.
Radek Brich <radek.brich@devl.cz>
parents: 95
diff changeset
   500
        mod_set = set()
0c2e0c09ba5c Add TextField widget, keypress event, cursor.
Radek Brich <radek.brich@devl.cz>
parents: 95
diff changeset
   501
        for bit, name in enumerate(('shift', 'alt', 'ctrl', 'meta')):
0c2e0c09ba5c Add TextField widget, keypress event, cursor.
Radek Brich <radek.brich@devl.cz>
parents: 95
diff changeset
   502
            if mod_bits & 1<<bit:
0c2e0c09ba5c Add TextField widget, keypress event, cursor.
Radek Brich <radek.brich@devl.cz>
parents: 95
diff changeset
   503
                mod_set.add(name)
0c2e0c09ba5c Add TextField widget, keypress event, cursor.
Radek Brich <radek.brich@devl.cz>
parents: 95
diff changeset
   504
0c2e0c09ba5c Add TextField widget, keypress event, cursor.
Radek Brich <radek.brich@devl.cz>
parents: 95
diff changeset
   505
        return [('keypress', keyname, None, mod_set)]
86
0978fb755d31 Add core Application (adjusted), Window (new version), Signal (replaces Emitter), Size (adjusted). Add application demo.
Radek Brich <radek.brich@devl.cz>
parents: 84
diff changeset
   506
0978fb755d31 Add core Application (adjusted), Window (new version), Signal (replaces Emitter), Size (adjusted). Add application demo.
Radek Brich <radek.brich@devl.cz>
parents: 84
diff changeset
   507
0978fb755d31 Add core Application (adjusted), Window (new version), Signal (replaces Emitter), Size (adjusted). Add application demo.
Radek Brich <radek.brich@devl.cz>
parents: 84
diff changeset
   508
driver_class = CursesDriver