Ejemplo n.º 1
0
    def process_event(self, event):
        if isinstance(event, KeyboardEvent):
            if event.key_code == Screen.KEY_BACK and not self._readonly:
                if self._column > 0:
                    # Delete character in front of cursor.
                    self._set_and_check_value("".join([
                        self._value[:self._column - 1],
                        self._value[self._column:]
                    ]))
                    self._column -= 1
            elif event.key_code == Screen.KEY_DELETE and not self._readonly:
                if self._column < len(self._value):
                    self._set_and_check_value("".join([
                        self._value[:self._column],
                        self._value[self._column + 1:]
                    ]))
            elif event.key_code == Screen.KEY_LEFT:
                self._column -= 1
                self._column = max(self._column, 0)
            elif event.key_code == Screen.KEY_RIGHT:
                self._column += 1
                self._column = min(len(self._value), self._column)
            elif event.key_code == Screen.KEY_HOME:
                self._column = 0
            elif event.key_code == Screen.KEY_END:
                self._column = len(self._value)
            elif event.key_code >= 32 and not self._readonly:
                # Enforce required max length - swallow event if not allowed
                if self._max_length is None or len(
                        self._value) < self._max_length:
                    # Insert any visible text at the current cursor position.
                    self._set_and_check_value(
                        chr(event.key_code).join([
                            self._value[:self._column],
                            self._value[self._column:]
                        ]))
                    self._column += 1
            else:
                # Ignore any other key press.
                return event
        elif isinstance(event, MouseEvent):
            # Mouse event - rebase coordinates to Frame context.
            if event.buttons != 0:
                if self.is_mouse_over(event, include_label=False):
                    self._column = (self._start_column + _get_offset(
                        self._value[self._start_column:], event.x - self._x -
                        self._offset, self._frame.canvas.unicode_aware))
                    self._column = min(len(self._value), self._column)
                    self._column = max(0, self._column)
                    return None
            # Ignore other mouse events.
            return event
        else:
            # Ignore other events
            return event

        # If we got here, we processed the event - swallow it.
        return None
Ejemplo n.º 2
0
    def process_event(self, event):
        def _join(a, b):
            if self._parser:
                return ColouredText(a, self._parser,
                                    colour=b[0].first_colour).join(b)
            return a.join(b)

        if isinstance(event, KeyboardEvent):
            old_value = copy(self._value)
            if event.key_code in [10, 13] and not self._readonly:
                # Split and insert line  on CR or LF.
                self._value.insert(self._line + 1,
                                   self._value[self._line][self._column:])
                self._value[self._line] = self._value[
                    self._line][:self._column]
                self._line += 1
                self._column = 0
            elif event.key_code == Screen.KEY_BACK and not self._readonly:
                if self._column > 0:
                    # Delete character in front of cursor.
                    self._value[self._line] = _join("", [
                        self._value[self._line][:self._column - 1],
                        self._value[self._line][self._column:]
                    ])
                    self._column -= 1
                else:
                    if self._line > 0:
                        # Join this line with previous
                        self._line -= 1
                        self._column = len(self._value[self._line])
                        self._value[self._line] += \
                            self._value.pop(self._line + 1)
            elif event.key_code == Screen.KEY_DELETE and not self._readonly:
                if self._column < len(self._value[self._line]):
                    self._value[self._line] = _join("", [
                        self._value[self._line][:self._column],
                        self._value[self._line][self._column + 1:]
                    ])
                else:
                    if self._line < len(self._value) - 1:
                        # Join this line with next
                        self._value[self._line] += \
                            self._value.pop(self._line + 1)
            elif event.key_code == Screen.KEY_PAGE_UP:
                self._change_line(-self._h)
            elif event.key_code == Screen.KEY_PAGE_DOWN:
                self._change_line(self._h)
            elif event.key_code == Screen.KEY_UP:
                self._change_line(-1)
            elif event.key_code == Screen.KEY_DOWN:
                self._change_line(1)
            elif event.key_code == Screen.KEY_LEFT:
                # Move left one char, wrapping to previous line if needed.
                self._column -= 1
                if self._column < 0:
                    if self._line > 0:
                        self._line -= 1
                        self._column = len(self._value[self._line])
                    else:
                        self._column = 0
            elif event.key_code == Screen.KEY_RIGHT:
                # Move right one char, wrapping to next line if needed.
                self._column += 1
                if self._column > len(self._value[self._line]):
                    if self._line < len(self._value) - 1:
                        self._line += 1
                        self._column = 0
                    else:
                        self._column = len(self._value[self._line])
            elif event.key_code == Screen.KEY_HOME:
                # Go to the start of this line
                self._column = 0
            elif event.key_code == Screen.KEY_END:
                # Go to the end of this line
                self._column = len(self._value[self._line])
            elif event.key_code >= 32 and not self._readonly:
                # Insert any visible text at the current cursor position.
                self._value[self._line] = _join(chr(event.key_code), [
                    self._value[self._line][:self._column],
                    self._value[self._line][self._column:]
                ])
                self._column += 1
            else:
                # Ignore any other key press.
                return event

            # If we got here we might have changed the value...
            if old_value != self._value:
                self._reflowed_text_cache = None
                if self._on_change:
                    self._on_change()

        elif isinstance(event, MouseEvent):
            # Mouse event - rebase coordinates to Frame context.
            if event.buttons != 0:
                if self.is_mouse_over(event, include_label=False):
                    # Find the line first.
                    clicked_line = event.y - self._y + self._start_line
                    if self._line_wrap:
                        # Line-wrapped text needs to be mapped to visible lines
                        display_text = self._reflowed_text
                        clicked_line = min(clicked_line, len(display_text) - 1)
                        text_line = display_text[clicked_line][1]
                        text_col = display_text[clicked_line][2]
                    else:
                        # non-wrapped just needs a little end protection
                        text_line = max(0, clicked_line)
                        text_col = 0
                    self._line = min(len(self._value) - 1, text_line)

                    # Now figure out location in text based on width of each glyph.
                    self._column = (
                        self._start_column + text_col + _get_offset(
                            str(self._value[self._line][self._start_column +
                                                        text_col:]),
                            event.x - self._x - self._offset,
                            self._frame.canvas.unicode_aware))
                    self._column = min(len(self._value[self._line]),
                                       self._column)
                    self._column = max(0, self._column)
                    return None
            # Ignore other mouse events.
            return event
        else:
            # Ignore other events
            return event

        # If we got here, we processed the event - swallow it.
        return None