예제 #1
0
파일: text.py 프로젝트: saebyn/nwgui
class Text(Container):
    def __init__(self, text, width, height, background=(255, 255, 255),
                       *args, **kwargs):
        kwargs['border'] = (1, (0, 0, 0))
        Container.__init__(self, width, height, *args, **kwargs)
        self.cursorPosition = 0
        self.text = ""

        self.textDisplayedBeginIndex = 0

        self.cursor = Image('textcursor', root=self.root)
        self.add(self.cursor)

        self.label = Label('', root=self.root, fontSize=30)
        self.add(self.label)

    @property
    def textDisplayedEndIndex(self):
        for index in xrange(len(self.text),
                            self.textDisplayedBeginIndex + 1,
                            -1):
            text = self.text[self.textDisplayedBeginIndex:index]
            if self.label.font.size(text)[0] < self.rect.width - 4:
                return index

        return self.textDisplayedBeginIndex + 1

    def setPosition(self, position):
        Container.setPosition(self, position)

        x, y = position

        self.cursor.setPosition(self._cursorPosition())

        self.label.setPosition((x + 3, y))
        self.label.rect.bottom = self.rect.bottom - 2

    def update(self, *args):
        Container.update(self, *args)
        self.cursor.setPosition(self._cursorPosition())
        self.label.setText(self._viewableText())
        self.label.changeLayer(self.layer + 1)
        self.cursor.changeLayer(self.layer + 2)

    def _viewableText(self):
        return self.text[self.textDisplayedBeginIndex:self.textDisplayedEndIndex]

    def _relativeCursorPosition(self):
        if self.cursorPosition < self.textDisplayedBeginIndex:
            self.textDisplayedBeginIndex = self.cursorPosition

        while self.textDisplayedEndIndex < self.cursorPosition:
            self.textDisplayedBeginIndex += 1

        return self.cursorPosition - self.textDisplayedBeginIndex

    def _cursorPosition(self):
        beforeCursorViewableText = self._viewableText()[:self._relativeCursorPosition()]

        return (self.label.font.size(beforeCursorViewableText)[0] + \
                self.rect.left,
                self.rect.top + 2)

    def moveCursorRight(self):
        if self.cursorPosition >= len(self.text):
            return

        self.cursorPosition += 1

        if self.cursor.rect.right > self.rect.right:
            self.cursor.rect.right = self.rect.right

    def moveCursorLeft(self):
        if self.cursorPosition == 0:
            return

        self.cursorPosition -= 1

        if self.cursor.rect.left < self.rect.left:
            self.cursor.rect.left = self.rect.left

    def deleteCharacter(self):
        # Can't delete anything if there's no text.
        if len(self.text) == 0:
            return

        self.text = self.text[:self.cursorPosition] + \
                    self.text[self.cursorPosition + 1:]
        self.cursor.setPosition(self._cursorPosition())

    def addCharacter(self, character):
        self.text += character
        self.moveCursorRight()

    def handleEvent(self, event):
        if event.type == MOUSEBUTTONDOWN and event.button == 1:
            self.setActive()
            # TODO support mouse insert-cursor selection
        elif event.type == KEYDOWN:
            if event.key == K_LEFT:
                self.moveCursorLeft()
            elif event.key == K_RIGHT:
                self.moveCursorRight()
            elif event.key == K_DELETE:
                self.deleteCharacter()
            elif event.key == K_BACKSPACE:
                self.moveCursorLeft()
                self.deleteCharacter()
            elif event.unicode in string.printable and event.unicode not in '\n\r\x0b\x0c':
                self.addCharacter(event.unicode)