예제 #1
0
def calc_pos(text, layout, pref_col, row):
    """
    Calculate the closest linear position to pref_col and row given a
    layout structure.
    """

    if row < 0 or row >= len(layout):
        raise Exception("calculate_pos: out of layout row range")

    pos = calc_line_pos(text, layout[row], pref_col)
    if pos is not None:
        return pos

    rows_above = list(xrange(row - 1, -1, -1))
    rows_below = list(xrange(row + 1, len(layout)))
    while rows_above and rows_below:
        if rows_above:
            r = rows_above.pop(0)
            pos = calc_line_pos(text, layout[r], pref_col)
            if pos is not None: return pos
        if rows_below:
            r = rows_below.pop(0)
            pos = calc_line_pos(text, layout[r], pref_col)
            if pos is not None: return pos
    return 0
예제 #2
0
    def erase(self, start, end):
        """
        Erase a region of the terminal. The 'start' tuple (x, y) defines the
        starting position of the erase, while end (x, y) the last position.

        For example if the terminal size is 4x3, start=(1, 1) and end=(1, 2)
        would erase the following region:

        ....
        .XXX
        XX..
        """
        sx, sy = self.constrain_coords(*start)
        ex, ey = self.constrain_coords(*end)

        # within a single row
        if sy == ey:
            for x in xrange(sx, ex + 1):
                self.term[sy][x] = self.empty_char()
            return

        # spans multiple rows
        y = sy
        while y <= ey:
            if y == sy:
                for x in xrange(sx, self.width):
                    self.term[y][x] = self.empty_char()
            elif y == ey:
                for x in xrange(ex + 1):
                    self.term[y][x] = self.empty_char()
            else:
                self.blank_line(y)

            y += 1
예제 #3
0
파일: vterm.py 프로젝트: andy-z/urwid
    def erase(self, start, end):
        """
        Erase a region of the terminal. The 'start' tuple (x, y) defines the
        starting position of the erase, while end (x, y) the last position.

        For example if the terminal size is 4x3, start=(1, 1) and end=(1, 2)
        would erase the following region:

        ....
        .XXX
        XX..
        """
        sx, sy = self.constrain_coords(*start)
        ex, ey = self.constrain_coords(*end)

        # within a single row
        if sy == ey:
            for x in xrange(sx, ex + 1):
                self.term[sy][x] = self.empty_char()
            return

        # spans multiple rows
        y = sy
        while y <= ey:
            if y == sy:
                for x in xrange(sx, self.width):
                    self.term[y][x] = self.empty_char()
            elif y == ey:
                for x in xrange(ex + 1):
                    self.term[y][x] = self.empty_char()
            else:
                self.blank_line(y)

            y += 1
예제 #4
0
파일: text_layout.py 프로젝트: andy-z/urwid
def calc_pos( text, layout, pref_col, row ):
    """
    Calculate the closest linear position to pref_col and row given a
    layout structure.
    """

    if row < 0 or row >= len(layout):
        raise Exception("calculate_pos: out of layout row range")

    pos = calc_line_pos( text, layout[row], pref_col )
    if pos is not None:
        return pos

    rows_above = list(xrange(row-1,-1,-1))
    rows_below = list(xrange(row+1,len(layout)))
    while rows_above and rows_below:
        if rows_above:
            r = rows_above.pop(0)
            pos = calc_line_pos(text, layout[r], pref_col)
            if pos is not None: return pos
        if rows_below:
            r = rows_below.pop(0)
            pos = calc_line_pos(text, layout[r], pref_col)
            if pos is not None: return pos
    return 0
예제 #5
0
    def _adjust_focus_on_contents_modified(self, slc, new_items=()):
        """
        Default behaviour is to move the focus to the item following
        any removed items, unless that item was simply replaced.

        Failing that choose the last item in the list.

        returns focus position for after change is applied
        """
        num_new_items = len(new_items)
        start, stop, step = indices = slc.indices(len(self))
        num_removed = len(list(xrange(*indices)))

        focus = self._validate_contents_modified(indices, new_items)
        if focus is not None:
            return focus

        focus = self._focus
        if step == 1:
            if start + num_new_items <= focus < stop:
                focus = stop
            # adjust for added/removed items
            if stop <= focus:
                focus += num_new_items - (stop - start)

        else:
            if not num_new_items:
                # extended slice being removed
                if focus in xrange(start, stop, step):
                    focus += 1

                # adjust for removed items
                focus -= len(list(xrange(start, min(focus, stop), step)))

        return min(focus, len(self) + num_new_items - num_removed -1)
예제 #6
0
    def _adjust_focus_on_contents_modified(self, slc, new_items=()):
        """
        Default behaviour is to move the focus to the item following
        any removed items, unless that item was simply replaced.

        Failing that choose the last item in the list.

        returns focus position for after change is applied
        """
        num_new_items = len(new_items)
        start, stop, step = indices = slc.indices(len(self))
        num_removed = len(list(xrange(*indices)))

        focus = self._validate_contents_modified(indices, new_items)
        if focus is not None:
            return focus

        focus = self._focus
        if step == 1:
            if start + num_new_items <= focus < stop:
                focus = stop
            # adjust for added/removed items
            if stop <= focus:
                focus += num_new_items - (stop - start)

        else:
            if not num_new_items:
                # extended slice being removed
                if focus in xrange(start, stop, step):
                    focus += 1

                # adjust for removed items
                focus -= len(list(xrange(start, min(focus, stop), step)))

        return min(focus, len(self) + num_new_items - num_removed - 1)
예제 #7
0
 def reverse_video(self, undo=False):
     """
     Reverse video/scanmode (DECSCNM) by swapping fg and bg colors.
     """
     for y in xrange(self.height):
         for x in xrange(self.width):
             char = self.term[y][x]
             attrs = self.reverse_attrspec(char[0], undo=undo)
             self.term[y][x] = (attrs, ) + char[1:]
예제 #8
0
파일: vterm.py 프로젝트: andy-z/urwid
 def reverse_video(self, undo=False):
     """
     Reverse video/scanmode (DECSCNM) by swapping fg and bg colors.
     """
     for y in xrange(self.height):
         for x in xrange(self.width):
             char = self.term[y][x]
             attrs = self.reverse_attrspec(char[0], undo=undo)
             self.term[y][x] = (attrs,) + char[1:]
예제 #9
0
파일: vterm.py 프로젝트: andy-z/urwid
    def resize(self, width, height):
        """
        Resize the terminal to the given width and height.
        """
        x, y = self.term_cursor

        if width > self.width:
            # grow
            for y in xrange(self.height):
                self.term[y] += [self.empty_char()] * (width - self.width)
        elif width < self.width:
            # shrink
            for y in xrange(self.height):
                self.term[y] = self.term[y][:width]

        self.width = width

        if height > self.height:
            # grow
            for y in xrange(self.height, height):
                try:
                    last_line = self.scrollback_buffer.pop()
                except IndexError:
                    # nothing in scrollback buffer, append an empty line
                    self.term.append(self.empty_line())
                    self.scrollregion_end += 1
                    continue

                # adjust x axis of scrollback buffer to the current width
                if len(last_line) < self.width:
                    last_line += [self.empty_char()] * \
                                 (self.width - len(last_line))
                else:
                    last_line = last_line[:self.width]

                y += 1

                self.term.insert(0, last_line)
        elif height < self.height:
            # shrink
            for y in xrange(height, self.height):
                self.scrollback_buffer.append(self.term.pop(0))

        self.height = height

        self.reset_scroll()

        x, y = self.constrain_coords(x, y)
        self.set_term_cursor(x, y)

        # extend tabs
        self.init_tabstops(extend=True)
예제 #10
0
    def resize(self, width, height):
        """
        Resize the terminal to the given width and height.
        """
        x, y = self.term_cursor

        if width > self.width:
            # grow
            for y in xrange(self.height):
                self.term[y] += [self.empty_char()] * (width - self.width)
        elif width < self.width:
            # shrink
            for y in xrange(self.height):
                self.term[y] = self.term[y][:width]

        self.width = width

        if height > self.height:
            # grow
            for y in xrange(self.height, height):
                try:
                    last_line = self.scrollback_buffer.pop()
                except IndexError:
                    # nothing in scrollback buffer, append an empty line
                    self.term.append(self.empty_line())
                    self.scrollregion_end += 1
                    continue

                # adjust x axis of scrollback buffer to the current width
                if len(last_line) < self.width:
                    last_line += [self.empty_char()] * \
                                 (self.width - len(last_line))
                else:
                    last_line = last_line[:self.width]

                y += 1

                self.term.insert(0, last_line)
        elif height < self.height:
            # shrink
            for y in xrange(height, self.height):
                self.scrollback_buffer.append(self.term.pop(0))

        self.height = height

        self.reset_scroll()

        x, y = self.constrain_coords(x, y)
        self.set_term_cursor(x, y)

        # extend tabs
        self.init_tabstops(extend=True)
예제 #11
0
파일: vterm.py 프로젝트: andy-z/urwid
    def parse_csi(self, char):
        """
        Parse ECMA-48 CSI (Control Sequence Introducer) sequences.
        """
        qmark = self.escbuf.startswith(B('?'))

        escbuf = []
        for arg in self.escbuf[qmark and 1 or 0:].split(B(';')):
            try:
                num = int(arg)
            except ValueError:
                num = None

            escbuf.append(num)

        if CSI_COMMANDS[char] is not None:
            if CSI_COMMANDS[char][0] == 'alias':
                csi_cmd = CSI_COMMANDS[(CSI_COMMANDS[char][1])]
            else:
                csi_cmd = CSI_COMMANDS[char]

            number_of_args, default_value, cmd = csi_cmd
            while len(escbuf) < number_of_args:
                escbuf.append(default_value)
            for i in xrange(len(escbuf)):
                if escbuf[i] is None or escbuf[i] == 0:
                    escbuf[i] = default_value

            try:
                cmd(self, escbuf, qmark)
            except ValueError:
                # ignore commands that don't match the
                # unpacked tuples in CSI_COMMANDS.
                pass
예제 #12
0
    def parse_csi(self, char):
        """
        Parse ECMA-48 CSI (Control Sequence Introducer) sequences.
        """
        qmark = self.escbuf.startswith(B('?'))

        escbuf = []
        for arg in self.escbuf[qmark and 1 or 0:].split(B(';')):
            try:
                num = int(arg)
            except ValueError:
                num = None

            escbuf.append(num)

        if CSI_COMMANDS[char] is not None:
            if CSI_COMMANDS[char][0] == 'alias':
                csi_cmd = CSI_COMMANDS[(CSI_COMMANDS[char][1])]
            else:
                csi_cmd = CSI_COMMANDS[char]

            number_of_args, default_value, cmd = csi_cmd
            while len(escbuf) < number_of_args:
                escbuf.append(default_value)
            for i in xrange(len(escbuf)):
                if escbuf[i] is None or escbuf[i] == 0:
                    escbuf[i] = default_value

            try:
                cmd(self, escbuf, qmark)
            except ValueError:
                # ignore commands that don't match the
                # unpacked tuples in CSI_COMMANDS.
                pass
예제 #13
0
    def _setup_colour_pairs(self):
        """
        Initialize all 63 color pairs based on the term:
        bg * 8 + 7 - fg
        So to get a color, we just need to use that term and get the right color
        pair number.
        """
        if not self.has_color:
            return

        for fg in xrange(8):
            for bg in xrange(8):
                # leave out white on black
                if fg == curses.COLOR_WHITE and \
                   bg == curses.COLOR_BLACK:
                    continue

                curses.init_pair(bg * 8 + 7 - fg, fg, bg)
예제 #14
0
    def _setup_colour_pairs(self):
        """
        Initialize all 63 color pairs based on the term:
        bg * 8 + 7 - fg
        So to get a color, we just need to use that term and get the right color
        pair number.
        """
        if not self.has_color:
            return

        for fg in xrange(8):
            for bg in xrange(8):
                # leave out white on black
                if fg == curses.COLOR_WHITE and \
                   bg == curses.COLOR_BLACK:
                    continue

                curses.init_pair(bg * 8 + 7 - fg, fg, bg)
예제 #15
0
파일: vterm.py 프로젝트: andy-z/urwid
    def clear(self, cursor=None):
        """
        Clears the whole terminal screen and resets the cursor position
        to (0, 0) or to the coordinates given by 'cursor'.
        """
        self.term = [self.empty_line() for x in xrange(self.height)]

        if cursor is None:
            self.set_term_cursor(0, 0)
        else:
            self.set_term_cursor(*cursor)
예제 #16
0
    def clear(self, cursor=None):
        """
        Clears the whole terminal screen and resets the cursor position
        to (0, 0) or to the coordinates given by 'cursor'.
        """
        self.term = [self.empty_line() for x in xrange(self.height)]

        if cursor is None:
            self.set_term_cursor(0, 0)
        else:
            self.set_term_cursor(*cursor)
예제 #17
0
    def set_tabstop(self, x=None, remove=False, clear=False):
        if clear:
            for tab in xrange(len(self.tabstops)):
                self.tabstops[tab] = 0
            return

        if x is None:
            x = self.term_cursor[0]

        div, mod = divmod(x, 8)
        if remove:
            self.tabstops[div] &= ~(1 << mod)
        else:
            self.tabstops[div] |= (1 << mod)
예제 #18
0
파일: vterm.py 프로젝트: andy-z/urwid
    def set_tabstop(self, x=None, remove=False, clear=False):
        if clear:
            for tab in xrange(len(self.tabstops)):
                self.tabstops[tab] = 0
            return

        if x is None:
            x = self.term_cursor[0]

        div, mod = divmod(x, 8)
        if remove:
            self.tabstops[div] &= ~(1 << mod)
        else:
            self.tabstops[div] |= (1 << mod)
예제 #19
0
파일: vterm.py 프로젝트: andy-z/urwid
 def decaln(self):
     """
     DEC screen alignment test: Fill screen with E's.
     """
     for row in xrange(self.height):
         self.term[row] = self.empty_line('E')
예제 #20
0
 def decaln(self):
     """
     DEC screen alignment test: Fill screen with E's.
     """
     for row in xrange(self.height):
         self.term[row] = self.empty_line('E')
예제 #21
0
from __future__ import division, print_function

import os
import sys

try:
    import termios
except ImportError:
    pass  # windows

from urwid.util import StoppingContext, int_scale
from urwid import signals
from urwid.compat import B, bytes3, xrange, with_metaclass

# for replacing unprintable bytes with '?'
UNPRINTABLE_TRANS_TABLE = B("?") * 32 + bytes3(list(xrange(32, 256)))

# signals sent by BaseScreen
UPDATE_PALETTE_ENTRY = "update palette entry"
INPUT_DESCRIPTORS_CHANGED = "input descriptors changed"

# AttrSpec internal values
_BASIC_START = 0  # first index of basic color aliases
_CUBE_START = 16  # first index of color cube
_CUBE_SIZE_256 = 6  # one side of the color cube
_GRAY_SIZE_256 = 24
_GRAY_START_256 = _CUBE_SIZE_256**3 + _CUBE_START
_CUBE_WHITE_256 = _GRAY_START_256 - 1
_CUBE_SIZE_88 = 4
_GRAY_SIZE_88 = 8
_GRAY_START_88 = _CUBE_SIZE_88**3 + _CUBE_START
예제 #22
0
from __future__ import division, print_function

import os
import sys

try:
    import termios
except ImportError:
    pass # windows

from urwid.util import StoppingContext, int_scale
from urwid import signals
from urwid.compat import B, bytes3, xrange, with_metaclass

# for replacing unprintable bytes with '?'
UNPRINTABLE_TRANS_TABLE = B("?") * 32 + bytes3(list(xrange(32,256)))


# signals sent by BaseScreen
UPDATE_PALETTE_ENTRY = "update palette entry"
INPUT_DESCRIPTORS_CHANGED = "input descriptors changed"


# AttrSpec internal values
_BASIC_START = 0 # first index of basic color aliases
_CUBE_START = 16 # first index of color cube
_CUBE_SIZE_256 = 6 # one side of the color cube
_GRAY_SIZE_256 = 24
_GRAY_START_256 = _CUBE_SIZE_256 ** 3 + _CUBE_START
_CUBE_WHITE_256 = _GRAY_START_256 -1
_CUBE_SIZE_88 = 4