Mercurial > lcfOS
view python/codeedit.py @ 160:10330be89bc2
Started from scratch with code edit
author | Windel Bouwman |
---|---|
date | Sat, 09 Mar 2013 11:56:48 +0100 |
parents | |
children | 956f8e5ee48a |
line wrap: on
line source
#!/usr/bin/python import sys from PyQt4.QtCore import * from PyQt4.QtGui import * import inspect GAP = 5 def clipVal(v, mn, mx): if v < mn: return mn if v > mx: return mx return v class InnerCode(QWidget): def __init__(self, scrollArea): super().__init__(scrollArea) self.scrollArea = scrollArea self.setFont(QFont('Courier', 16)) self.setFocusPolicy(Qt.StrongFocus) self.blinkcursor = False # Initial values: self.setSource('') self.CursorPosition = 0 t = QTimer(self) t.timeout.connect(self.updateCursor) t.setInterval(500) t.start() def updateCursor(self): self.blinkcursor = not self.blinkcursor self.update(self.cursorX, self.cursorY, self.charWidth, self.charHeight) def setSource(self, src): self.src = src self.adjust() def setCursorPosition(self, c): self.cursorPosition = clipVal(c, 0, len(self.src)) print(self.cursorPosition, self.CursorRow, self.CursorCol) self.cursorX = self.CursorCol * self.charWidth + self.xposTXT - self.charWidth self.cursorY = self.CursorRow * self.charHeight - self.charHeight CursorPosition = property(lambda self: self.cursorPosition, setCursorPosition) @property def CursorRow(self): # TODO: make this nice. txt = self.src[0:self.cursorPosition] return len(txt.split('\n')) @property def CursorCol(self): txt = self.src[0:self.cursorPosition] curLine = txt.split('\n')[-1] return len(curLine) + 1 @property def CurrentLine(self): return self.getRow(self.CursorRow) def getRow(self, r): rows = self.src.split('\n') r = r - 1 if r < 0 or r > len(rows) - 1: return '' else: return rows[r] def getChar(self, pos): pass def insertText(self, txt): self.setSource(self.src[0:self.CursorPosition] + txt + self.src[self.CursorPosition:]) self.CursorPosition += len(txt) def GotoNextChar(self): if self.src[self.CursorPosition] != '\n': self.CursorPosition += 1 def GotoPrevChar(self): if self.src[self.CursorPosition - 1] != '\n': self.CursorPosition -= 1 def GotoNextLine(self): curLine = self.CurrentLine c = self.CursorCol self.CursorPosition += len(curLine) - c + c + 1 # line break char! def GotoPrevLine(self): curLine = self.CurrentLine c = self.CursorCol self.CursorPosition -= len(curLine) + c + 1 # line break char! def paintEvent(self, event): # Helper variables: er = event.rect() chw, chh = self.charWidth, self.charHeight painter = QPainter(self) # Background: painter.fillRect(er, self.palette().color(QPalette.Base)) painter.fillRect(QRect(self.xposLNA, er.top(), 8 * chw, er.bottom() + 1), Qt.gray) painter.fillRect(self.xposTXT, (self.CursorRow - 1) * chh, er.width(), chh, Qt.yellow) painter.setPen(Qt.gray) # first and last row: row1 = max(int(er.top() / chh) - 1, 0) row2 = max(int(er.bottom() / chh) + 1, 0) # Draw contents: txt = self.src.split('\n') print('update', row1, row2) for row in range(row1, row2 + 1): ypos = row * chh painter.setPen(Qt.black) painter.drawText(self.xposLNA, ypos, 'R ={0}'.format(row)) xpos = self.xposTXT if row - 1 < len(txt): painter.drawText(xpos, ypos, txt[row - 1]) # cursor if self.blinkcursor: painter.fillRect(self.cursorX, self.cursorY, 2, chh, Qt.black) def keyPressEvent(self, event): if event.matches(QKeySequence.MoveToNextChar): self.GotoNextChar() if event.matches(QKeySequence.MoveToPreviousChar): self.GotoPrevChar() if event.matches(QKeySequence.MoveToNextLine): self.GotoNextLine() if event.matches(QKeySequence.MoveToPreviousLine): self.GotoPrevLine() if event.matches(QKeySequence.MoveToNextPage): for i in range(5): self.GotoNextLine() if event.matches(QKeySequence.MoveToPreviousPage): for i in range(5): self.GotoPrevLine() if event.matches(QKeySequence.MoveToEndOfLine): self.CursorPosition += len(self.CurrentLine) - self.CursorCol + 1 if event.matches(QKeySequence.MoveToStartOfLine): self.CursorPosition -= self.CursorCol - 1 char = event.text().lower() if char: print('ins', char) self.insertText(char) self.update() def adjust(self): self.charHeight = self.fontMetrics().height() self.charWidth = self.fontMetrics().width('x') self.xposLNA = GAP self.xposTXT = self.xposLNA + 8 * self.charWidth + GAP self.xposEnd = self.xposTXT + self.charWidth * 80 self.setMinimumWidth(self.xposEnd) txt = self.src.split('\n') self.setMinimumHeight(self.charHeight * len(txt)) self.update() class CodeEdit(QScrollArea): def __init__(self): super().__init__() self.ic = InnerCode(self) self.setWidget(self.ic) self.setWidgetResizable(True) self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn) self.setFocusPolicy(Qt.NoFocus) Source = property(lambda s: s.ic.getSource(), lambda s, v: s.ic.setSource(v)) if __name__ == '__main__': app = QApplication(sys.argv) ce = CodeEdit() ce.show() src = ''.join(inspect.getsourcelines(InnerCode)[0]) ce.Source = src ce.resize(600, 500) app.exec()