tuikit/driver/curses.py
author Radek Brich <radek.brich@devl.cz>
Wed, 26 Mar 2014 09:08:10 +0100
changeset 91 de80e140b0ec
parent 88 90d00354dc70
child 95 05392e369ede
permissions -rw-r--r--
Add clipping for Buffer draw operations.
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)
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
    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
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
   122
    def putch(self, x, y, ch):
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   123
        try:
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
   124
            if isinstance(ch, str) and len(ch) == 1:
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
   125
                self.stdscr.addstr(y, x, ch)
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   126
            else:
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.addch(y, x, ch)
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   128
        except curses.error:
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   129
            pass
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   130
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   131
    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
   132
        for bufy in range(buffer.size.h):
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   133
            for bufx in range(buffer.size.w):
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   134
                char, attr_desc = buffer.get(bufx, bufy)
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   135
                self.setattr(attr_desc)
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   136
                self.putch(x + bufx, y + bufy, char)
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   137
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   138
    def flush(self):
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   139
        if self.cursor:
83
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
   140
            self.stdscr.move(*self.cursor)
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   141
            curses.curs_set(True)
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   142
        else:
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   143
            curses.curs_set(False)
83
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
   144
        self.stdscr.refresh()
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   145
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   146
    ## colors, attributes ##
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   147
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   148
    def setattr(self, attr_desc):
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   149
        """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
   150
        attr = self.colors.get(attr_desc, None)
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   151
        if attr is None:
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   152
            # first encountered `attr_desc`, initialize
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   153
            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
   154
            fgcol, fgattr = self.color_map[fg]
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   155
            bgcol, _bgattr = self.color_map[bg]
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   156
            colpair = self._getcolorpair(fgcol, bgcol)
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   157
            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
   158
            self.colors[attr_desc] = attr
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   159
        self.stdscr.attrset(attr)
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   160
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   161
    def _getcolorpair(self, fgcol, bgcol):
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   162
        pair = (fgcol, bgcol)
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   163
        if pair in self.colorpairs:
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   164
            return self.colorpairs[pair]
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   165
        num = len(self.colorpairs) + 1
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   166
        curses.init_pair(num, fgcol, bgcol)
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   167
        self.colorpairs[pair] = num
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   168
        return num
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   169
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   170
    def _parseattrs(self, attrs):
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   171
        res = 0
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   172
        for a in attrs:
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   173
            res = res | self.attr_map[a]
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   174
        return res
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   175
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   176
    ## cursor ##
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   177
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   178
    def showcursor(self, x, y):
77
fc1989059e19 Propagate "quit" event, do not just terminate application. Resize: flag widgets to be resized, do resizes only once before draw. Draw: flag widgets to be redrawn, do not draw everything on any event.
Radek Brich <radek.brich@devl.cz>
parents: 71
diff changeset
   179
        if self.clipstack.test(x, y):
fc1989059e19 Propagate "quit" event, do not just terminate application. Resize: flag widgets to be resized, do resizes only once before draw. Draw: flag widgets to be redrawn, do not draw everything on any event.
Radek Brich <radek.brich@devl.cz>
parents: 71
diff changeset
   180
            self.cursor = (y, x)
fc1989059e19 Propagate "quit" event, do not just terminate application. Resize: flag widgets to be resized, do resizes only once before draw. Draw: flag widgets to be redrawn, do not draw everything on any event.
Radek Brich <radek.brich@devl.cz>
parents: 71
diff changeset
   181
        else:
fc1989059e19 Propagate "quit" event, do not just terminate application. Resize: flag widgets to be resized, do resizes only once before draw. Draw: flag widgets to be redrawn, do not draw everything on any event.
Radek Brich <radek.brich@devl.cz>
parents: 71
diff changeset
   182
            self.cursor = None
7
d4a291b31cbb New color management - named colors.
Radek Brich <radek.brich@devl.cz>
parents: 5
diff changeset
   183
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
   184
    def hidecursor(self):
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
   185
        curses.curs_set(False)
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
   186
        self.cursor = None
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   187
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   188
    ## input, events ##
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   189
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   190
    def getevents(self, timeout=None):
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   191
        """Process input, return list of events.
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   192
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   193
        timeout -- float, in seconds (None=infinite)
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
        Returns:
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   196
            [('event', param1, ...), ...]
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   197
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
        # empty queue -> fill
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   200
        if len(self.inputqueue) == 0:
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   201
            if timeout is not None:
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   202
                timeout = math.ceil(timeout * 10)
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   203
            self._inputqueue_fill(timeout)
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   204
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   205
        res = []
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   206
        while len(self.inputqueue):
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   207
            c = self._inputqueue_get()
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   208
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   209
            if c == curses.KEY_MOUSE:
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   210
                res += self._process_mouse()
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   211
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   212
            elif c == curses.KEY_RESIZE:
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   213
                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
   214
                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
   215
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   216
            elif curses.ascii.isctrl(c):
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   217
                self._inputqueue_unget(c)
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   218
                res += self._process_control_chars()
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   219
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   220
            elif 192 <= c <= 255:
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   221
                self._inputqueue_unget(c)
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   222
                res += self._process_utf8_chars()
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   223
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   224
            elif curses.ascii.isprint(c):
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   225
                res += [('keypress', None, str(chr(c)))]
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   226
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   227
            else:
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   228
                self._inputqueue_unget(c)
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   229
                res += self._process_control_chars()
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   230
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   231
        return res
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   232
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   233
    def _inputqueue_fill(self, timeout=None):
57
911927edbdde DriverSDL: Add support for timeouts.
Radek Brich <radek.brich@devl.cz>
parents: 46
diff changeset
   234
        """Wait for curses input, add it to inputqueue.
911927edbdde DriverSDL: Add support for timeouts.
Radek Brich <radek.brich@devl.cz>
parents: 46
diff changeset
   235
911927edbdde DriverSDL: Add support for timeouts.
Radek Brich <radek.brich@devl.cz>
parents: 46
diff changeset
   236
        timeout -- int, tenths of second (None=infinite)
911927edbdde DriverSDL: Add support for timeouts.
Radek Brich <radek.brich@devl.cz>
parents: 46
diff changeset
   237
911927edbdde DriverSDL: Add support for timeouts.
Radek Brich <radek.brich@devl.cz>
parents: 46
diff changeset
   238
        """
3
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   239
        if timeout is None:
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   240
            # wait indefinitely
83
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
   241
            c = self.stdscr.getch()
3
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   242
            self.inputqueue.insert(0, c)
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   243
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   244
        elif timeout > 0:
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   245
            # wait
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   246
            curses.halfdelay(timeout)
83
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
   247
            c = self.stdscr.getch()
3
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   248
            curses.cbreak()
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   249
            if c == -1:
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   250
                return
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   251
            self.inputqueue.insert(0, c)
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   252
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   253
        # timeout = 0 -> no wait
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   254
83
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
   255
        self.stdscr.nodelay(1)
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   256
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   257
        while True:
83
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
   258
            c = self.stdscr.getch()
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   259
            if c == -1:
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   260
                break
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   261
            self.inputqueue.insert(0, c)
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   262
83
ebe732b9ef19 Refactor Driver, CursesDriver: init, close, draw.
Radek Brich <radek.brich@devl.cz>
parents: 82
diff changeset
   263
        self.stdscr.nodelay(0)
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   264
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   265
    def _inputqueue_get(self):
3
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   266
        c = None
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   267
        try:
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   268
            c = self.inputqueue.pop()
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   269
        except IndexError:
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   270
            pass
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   271
        return c
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   272
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   273
    def _inputqueue_get_wait(self):
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   274
        c = None
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   275
        while c is None:
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   276
            try:
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   277
                c = self.inputqueue.pop()
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   278
            except IndexError:
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   279
                curses.napms(25)
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   280
                self._inputqueue_fill(0)
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   281
        return c
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   282
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   283
    def _inputqueue_unget(self, c):
3
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   284
        self.inputqueue.append(c)
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   285
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   286
    def _process_mouse(self):
4
d197ca00496f Add escape sequences for linux console.
Radek Brich <radek.brich@devl.cz>
parents: 3
diff changeset
   287
        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
   288
            _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
   289
        except curses.error:
d197ca00496f Add escape sequences for linux console.
Radek Brich <radek.brich@devl.cz>
parents: 3
diff changeset
   290
            return []
d197ca00496f Add escape sequences for linux console.
Radek Brich <radek.brich@devl.cz>
parents: 3
diff changeset
   291
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   292
        out = []
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   293
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   294
        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
   295
            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
   296
                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
   297
                    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
   298
                    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
   299
                    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
   300
                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
   301
bc51b0220be2 DriverCurses: filter mousemove - generate event only when coordinates changes.
Radek Brich <radek.brich@devl.cz>
parents: 66
diff changeset
   302
        # 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
   303
        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
   304
            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
   305
            new = bstate
bc51b0220be2 DriverCurses: filter mousemove - generate event only when coordinates changes.
Radek Brich <radek.brich@devl.cz>
parents: 66
diff changeset
   306
            bstate = ~old & new
bc51b0220be2 DriverCurses: filter mousemove - generate event only when coordinates changes.
Radek Brich <radek.brich@devl.cz>
parents: 66
diff changeset
   307
            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
   308
        else:
bc51b0220be2 DriverCurses: filter mousemove - generate event only when coordinates changes.
Radek Brich <radek.brich@devl.cz>
parents: 66
diff changeset
   309
            self._mouse_last_bstate = bstate
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   310
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   311
        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
   312
            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
   313
        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
   314
            out += [('mousedown', 2, x, y)]
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   315
        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
   316
            out += [('mousedown', 3, x, y)]
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   317
        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
   318
            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
   319
        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
   320
            out += [('mouseup', 2, x, y)]
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   321
        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
   322
            out += [('mouseup', 3, x, y)]
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   323
68
bc51b0220be2 DriverCurses: filter mousemove - generate event only when coordinates changes.
Radek Brich <radek.brich@devl.cz>
parents: 66
diff changeset
   324
        # 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
   325
        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
   326
            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
   327
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   328
        return out
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   329
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   330
    def _process_utf8_chars(self):
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   331
        #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
   332
        utf = []
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   333
        while len(utf) <= 6:
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   334
            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
   335
            utf.append(c)
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   336
            try:
20
472a753664f9 Update utf8 character input to Python3. Reorganize tests.
Radek Brich <radek.brich@devl.cz>
parents: 18
diff changeset
   337
                uni = str(bytes(utf), 'utf-8')
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   338
                return [('keypress', None, uni)]
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   339
            except UnicodeDecodeError:
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   340
                continue
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   341
        raise Exception('Invalid UTF-8 sequence: %r' % utf)
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   342
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   343
    def _process_control_chars(self):
65
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   344
        codes = self.key_codes
3
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   345
        matchingcodes = []
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   346
        match = None
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   347
        consumed = []
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   348
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   349
        # 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
   350
        c = self._inputqueue_get_wait()
3
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   351
        consumed.append(c)
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   352
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   353
        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
   354
            #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
   355
            for code in codes:
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   356
                if c == code[len(consumed)-1]:
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   357
                    if len(code) - 1 == len(consumed):
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   358
                        match = code
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   359
                    else:
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   360
                        matchingcodes += [code]
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   361
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
   362
            #self.log.debug('matching=%s', len(matchingcodes))
3
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   363
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   364
            # match found, or no matching code found -> stop
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   365
            if len(matchingcodes) == 0:
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   366
                break
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   367
3
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   368
            # match found and some sequencies still match -> continue
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   369
            if len(matchingcodes) > 0:
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   370
                if len(self.inputqueue) == 0:
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   371
                    self._inputqueue_fill(1)
3
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   372
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   373
            c = self._inputqueue_get()
3
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   374
            if c:
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   375
                consumed.append(c)
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   376
                codes = matchingcodes
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   377
                matchingcodes = []
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   378
            else:
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   379
                break
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   380
3
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   381
        keyname = None
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   382
        if match:
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   383
            # compare match to consumed, return unused chars
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   384
            l = len(match) - 1
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   385
            while len(consumed) > l:
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   386
                self._inputqueue_unget(consumed[-1])
3
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   387
                del consumed[-1]
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   388
            keyname = match[-1]
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   389
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   390
        if match is None:
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   391
            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
   392
                           ','.join(['0x%x' % x for x in consumed]))
3
33ec838dc021 Fixed escape sequence handling.
Radek Brich <radek.brich@devl.cz>
parents: 2
diff changeset
   393
            return [('keypress', 'Unknown', None)]
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   394
66
Radek Brich <radek.brich@devl.cz>
parents: 65
diff changeset
   395
        if keyname == 'mouse':
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   396
            return self._process_xterm_mouse()
66
Radek Brich <radek.brich@devl.cz>
parents: 65
diff changeset
   397
65
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   398
        if keyname == 'CSI':
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   399
            return self._process_control_sequence()
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   400
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   401
        return [('keypress', keyname, None)]
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   402
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   403
    def _process_xterm_mouse(self):
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   404
        t = self._inputqueue_get_wait()
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   405
        x = self._inputqueue_get_wait() - 0x21
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   406
        y = self._inputqueue_get_wait() - 0x21
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   407
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   408
        out = []
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   409
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 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
   411
            # button press
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   412
            btn = t - 0x1f
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   413
            if not btn in self.mbtnstack:
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   414
                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
   415
                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
   416
                out += [('mousedown', btn, x, y)]
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   417
            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
   418
                # mouse move
68
bc51b0220be2 DriverCurses: filter mousemove - generate event only when coordinates changes.
Radek Brich <radek.brich@devl.cz>
parents: 66
diff changeset
   419
                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
   420
                    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
   421
                        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
   422
                        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
   423
                        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
   424
                    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
   425
        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
   426
            # 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
   427
            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
   428
            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
   429
            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
   430
        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
   431
            # 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
   432
            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
   433
            out += [('mousewheel', btn, x, y)]
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   434
        else:
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   435
            raise Exception('Unknown mouse event: %x' % t)
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   436
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   437
        return out
29
c0cdef06fd16 Import only one driver from application.
Radek Brich <radek.brich@devl.cz>
parents: 27
diff changeset
   438
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   439
    def _process_control_sequence(self):
65
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   440
        codes = self.csi_codes
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   441
        debug_seq = [0x1b, 0x5b]
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   442
        c = self._inputqueue_get_wait()
65
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   443
        debug_seq.append(c)
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   444
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   445
        # numeric parameters?
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   446
        params = []
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   447
        if chr(c).isdigit():
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   448
            params.append(chr(c))
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   449
            while True:
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   450
                c = self._inputqueue_get_wait()
65
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   451
                debug_seq.append(c)
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   452
                if chr(c).isdigit():
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   453
                    params[-1] += chr(c)
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   454
                elif chr(c) == ';':
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   455
                    params.append('')
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   456
                else:
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   457
                    break
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   458
        params = [int(x) for x in params]
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   459
        if len(params) == 0:
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   460
            params = [1]
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   461
68
bc51b0220be2 DriverCurses: filter mousemove - generate event only when coordinates changes.
Radek Brich <radek.brich@devl.cz>
parents: 66
diff changeset
   462
        # filter codes using byte sequence
65
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   463
        while True:
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   464
            matching_codes = []
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   465
            for code in codes:
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   466
                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
   467
                    matching_codes.append(code[1:])
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   468
            codes = matching_codes
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   469
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   470
            if len(codes) == 0:
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   471
                # no match -> unknown code
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   472
                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
   473
                self.log.debug('Unknown control sequence: %s', seq)
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   474
                return [('keypress', 'Unknown:' + seq, None)]
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   475
            elif len(codes) == 1:
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   476
                # one match -> we got the winner
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   477
                break
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   478
            elif len(codes[0]) == 2:
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   479
                # 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
   480
                # will be sorted out using parameters
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   481
                break
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   482
            else:
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   483
                # more than one matching -> continue loop
84
04dfb5ddf031 Refactor Driver, CursesDriver: draw, setattr, input.
Radek Brich <radek.brich@devl.cz>
parents: 83
diff changeset
   484
                c = self._inputqueue_get_wait()
65
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   485
                debug_seq.append(c)
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   486
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   487
        # filter codes using first parameter
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   488
        matching_codes = []
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   489
        for code in codes:
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   490
            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
   491
                matching_codes.append(code)
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   492
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   493
        if len(matching_codes) == 0:
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   494
            # no match -> unknown code
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   495
            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
   496
            self.log.debug('Unknown control sequence: %s', seq)
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   497
            return [('keypress', 'Unknown:' + seq, None)]
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   498
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   499
        if len(matching_codes) > 1:
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   500
            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
   501
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   502
        keyname = matching_codes[0][1]
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   503
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   504
        # modifiers
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   505
        mod = 0
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   506
        if len(params) > 1:
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   507
            mod = params[1] - 1
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   508
5f0697950f15 DriverCurses: Add support for key modifiers.
Radek Brich <radek.brich@devl.cz>
parents: 57
diff changeset
   509
        return [('keypress', keyname, None, mod)]
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
   510
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
   511
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
   512
driver_class = CursesDriver