diff --git a/plugins/extensions/pykrita/plugin/plugins/scripter/ui_scripter/actions/settingsaction/syntaxstylescombobox.py b/plugins/extensions/pykrita/plugin/plugins/scripter/ui_scripter/actions/settingsaction/syntaxstylescombobox.py index 80a3c66c91..e079d66875 100644 --- a/plugins/extensions/pykrita/plugin/plugins/scripter/ui_scripter/actions/settingsaction/syntaxstylescombobox.py +++ b/plugins/extensions/pykrita/plugin/plugins/scripter/ui_scripter/actions/settingsaction/syntaxstylescombobox.py @@ -1,41 +1,41 @@ from PyQt5.QtWidgets import QComboBox from PyQt5.QtGui import QPalette from scripter.ui_scripter.syntax import syntaxstyles class SyntaxStylesComboBox(QComboBox): def __init__(self, highlight, editor, parent=None): super(SyntaxStylesComboBox, self).__init__(parent) self.highlight = highlight self.editor = editor - self.styleClasses = [syntaxstyles.DefaultSyntaxStyle, syntaxstyles.PythonVimSyntaxStyle] + self.styleClasses = [syntaxstyles.DefaultSyntaxStyle, syntaxstyles.PythonVimSyntaxStyle, syntaxstyles.BreezeLightSyntaxStyle, syntaxstyles.BreezeDarkSyntaxStyle, syntaxstyles.BlenderSyntaxStyle, syntaxstyles.SolarizedDarkSyntaxStyle, syntaxstyles.SolarizedLightSyntaxStyle] for styleClass in self.styleClasses: className = styleClass.__name__ self.addItem(className) if className == type(self.highlight.getSyntaxStyle()).__name__: self.setCurrentIndex(self.findText(className)) self.currentIndexChanged.connect(self._currentIndexChanged) def _currentIndexChanged(self, index): syntaxStyle = getattr(syntaxstyles, self.itemText(index))() self.highlight.setSyntaxStyle(syntaxStyle) self.highlight.rehighlight() p = self.editor.palette() p.setColor(QPalette.Base, syntaxStyle['background'].foreground().color()); p.setColor(QPalette.Text, syntaxStyle['foreground'].foreground().color()); self.editor.setPalette(p) self.editor.highlightCurrentLine() def readSettings(self, settings): syntaxStyle = settings.value('syntaxStyle', '') if syntaxStyle: self.setCurrentIndex(self.findText(syntaxStyle)) def writeSettings(self, settings): settings.setValue('syntaxStyle', type(self.highlight.getSyntaxStyle()).__name__) diff --git a/plugins/extensions/pykrita/plugin/plugins/scripter/ui_scripter/editor/pythoneditor.py b/plugins/extensions/pykrita/plugin/plugins/scripter/ui_scripter/editor/pythoneditor.py index 4b075509c9..47920d29d3 100644 --- a/plugins/extensions/pykrita/plugin/plugins/scripter/ui_scripter/editor/pythoneditor.py +++ b/plugins/extensions/pykrita/plugin/plugins/scripter/ui_scripter/editor/pythoneditor.py @@ -1,160 +1,160 @@ from PyQt5.QtCore import Qt, QRect, QSize, QPoint from PyQt5.QtWidgets import QPlainTextEdit, QTextEdit from PyQt5.QtGui import QIcon, QColor, QPainter, QTextFormat, QFont, QTextCursor, QPalette from scripter.ui_scripter.editor import linenumberarea, debugarea from scripter import resources_rc class CodeEditor(QPlainTextEdit): DEBUG_AREA_WIDTH = 20 def __init__(self, scripter, parent=None): super(CodeEditor, self).__init__(parent) self.setLineWrapMode(self.NoWrap) self.scripter = scripter self.lineNumberArea = linenumberarea.LineNumberArea(self) self.debugArea = debugarea.DebugArea(self) self.blockCountChanged.connect(self.updateMarginsWidth) self.updateRequest.connect(self.updateLineNumberArea) self.cursorPositionChanged.connect(self.highlightCurrentLine) self.updateMarginsWidth() self.highlightCurrentLine() self.font = "Monospace" self._stepped = False self.debugArrow = QIcon(':/icons/debug_arrow.svg') def debugAreaWidth(self): return self.DEBUG_AREA_WIDTH def lineNumberAreaWidth(self): """The lineNumberAreaWidth is the quatity of decimal places in blockCount""" digits = 1 max_ = max(1, self.blockCount()) while (max_ >= 10): max_ /= 10 digits += 1 space = 3 + self.fontMetrics().width('9') * digits return space def resizeEvent(self, event): super(CodeEditor, self).resizeEvent(event) qRect = self.contentsRect() self.debugArea.setGeometry(QRect(qRect.left(), qRect.top(), self.debugAreaWidth(), qRect.height())) self.lineNumberArea.setGeometry(QRect(qRect.left() + self.debugAreaWidth(), qRect.top(), self.lineNumberAreaWidth(), qRect.height())) def updateMarginsWidth(self): self.setViewportMargins(self.lineNumberAreaWidth() + self.debugAreaWidth(), 0, 0, 0) def updateLineNumberArea(self, rect, dy): """ This slot is invoked when the editors viewport has been scrolled """ if dy: self.lineNumberArea.scroll(0, dy) self.debugArea.scroll(0, dy) else: self.lineNumberArea.update(0, rect.y(), self.lineNumberArea.width(), rect.height()) if rect.contains(self.viewport().rect()): self.updateMarginsWidth() def lineNumberAreaPaintEvent(self, event): """This method draws the current lineNumberArea for while""" - blockColor = QColor(self.palette().base().color()).darker(250) + blockColor = QColor(self.palette().base().color()).darker(120) if (self.palette().base().color().lightness()<128): - blockColor = QColor(self.palette().base().color()).lighter(250) + blockColor = QColor(self.palette().base().color()).lighter(120) if (self.palette().base().color().lightness()<1): - blockColor = QColor(100, 100, 100) + blockColor = QColor(43, 43, 43) painter = QPainter(self.lineNumberArea) painter.fillRect(event.rect(), blockColor) block = self.firstVisibleBlock() blockNumber = block.blockNumber() top = int(self.blockBoundingGeometry(block).translated(self.contentOffset()).top()) bottom = top + int(self.blockBoundingRect(block).height()) while block.isValid() and top <= event.rect().bottom(): if block.isVisible() and bottom >= event.rect().top(): number = str(blockNumber + 1) - painter.setPen(self.palette().base().color()) + painter.setPen(self.palette().text().color()) painter.drawText(0, top, self.lineNumberArea.width(), self.fontMetrics().height(), Qt.AlignRight, number) block = block.next() top = bottom bottom = top + int(self.blockBoundingRect(block).height()) blockNumber += 1 def debugAreaPaintEvent(self, event): if self.scripter.debugcontroller.isActive and self.scripter.debugcontroller.currentLine: lineNumber = self.scripter.debugcontroller.currentLine block = self.document().findBlockByLineNumber(lineNumber - 1) if self._stepped: cursor = QTextCursor(block) self.setTextCursor(cursor) self._stepped = False top = int(self.blockBoundingGeometry(block).translated(self.contentOffset()).top()) bottom = top + int(self.blockBoundingRect(block).height()) painter = QPainter(self.debugArea) pixmap = self.debugArrow.pixmap(QSize(self.debugAreaWidth() - 3, int(self.blockBoundingRect(block).height()))) painter.drawPixmap(QPoint(0, top), pixmap) def highlightCurrentLine(self): """Highlight current line under cursor""" currentSelection = QTextEdit.ExtraSelection() lineColor = QColor(self.palette().base().color()).darker(120) if (self.palette().base().color().lightness()<128): lineColor = QColor(self.palette().base().color()).lighter(120) if (self.palette().base().color().lightness()<1): lineColor = QColor(43, 43, 43) currentSelection.format.setBackground(lineColor) currentSelection.format.setProperty(QTextFormat.FullWidthSelection, True) currentSelection.cursor = self.textCursor() currentSelection.cursor.clearSelection() self.setExtraSelections([currentSelection]) def wheelEvent(self, e): """When the CTRL is pressed during the wheelEvent, zoomIn and zoomOut slots are invoked""" if e.modifiers() == Qt.ControlModifier: delta = e.angleDelta().y() if delta < 0: self.zoomOut() elif delta > 0: self.zoomIn() else: super(CodeEditor, self).wheelEvent(e) @property def font(self): return self._font @font.setter def font(self, font): self._font = font self.setFont(QFont(font, 10)) def setStepped(self, status): self._stepped = status def repaintDebugArea(self): self.debugArea.repaint() diff --git a/plugins/extensions/pykrita/plugin/plugins/scripter/ui_scripter/syntax/syntaxstyles.py b/plugins/extensions/pykrita/plugin/plugins/scripter/ui_scripter/syntax/syntaxstyles.py index 44119fe1f8..5d04b3be9d 100644 --- a/plugins/extensions/pykrita/plugin/plugins/scripter/ui_scripter/syntax/syntaxstyles.py +++ b/plugins/extensions/pykrita/plugin/plugins/scripter/ui_scripter/syntax/syntaxstyles.py @@ -1,61 +1,166 @@ from PyQt5.QtGui import QColor, QTextCharFormat, QFont def format(color, style='', darker=100, lighter=100): """Return a QTextCharFormat with the given attributes. """ _color = QColor(color) _color = _color.darker(darker) _color = _color.lighter(lighter) _format = QTextCharFormat() _format.setForeground(_color) if 'bold' in style: _format.setFontWeight(QFont.Bold) if 'italic' in style: _format.setFontItalic(True) return _format class DefaultSyntaxStyle(object): # Syntax styles that combines with dark backgrounds STYLES = { 'keyword': format('cyan'), 'operator': format('orange'), 'brace': format('gray'), 'defclass': format('black', 'bold'), 'string': format('magenta'), 'string2': format('darkMagenta'), 'comment': format('darkGreen', 'italic'), 'self': format('black', 'italic'), 'numbers': format('brown'), 'background' : format('white'), 'foreground' : format('black'), } def __getitem__(self, key): return self.STYLES[key] class PythonVimSyntaxStyle(object): """ It based in the colorschemme of the Vim editor for python code http://www.vim.org/scripts/script.php?script_id=790 """ # Syntax styles that combines with dark backgrounds STYLES = { 'keyword': format('yellow', darker=125), 'operator': format('magenta', darker=150), 'brace': format('white'), 'defclass': format('orange', 'bold'), 'string': format('green', lighter=160), 'string2': format('lightGray', 'italic', darker=120), 'comment': format('gray', 'italic'), 'self': format('blue', lighter=170), 'numbers': format('yellow', lighter=130), 'background' : format('black'), 'foreground' : format('white'), } def __getitem__(self, key): return self.STYLES[key] + +class BreezeDarkSyntaxStyle(object): + + """ Based on KDE Breeze widget style """ + # A dark syntax style. + STYLES = { + 'keyword': format('#eff0f1'), + 'operator': format('#eff0f1'), + 'brace': format('#eff0f1'), + 'defclass': format('#27ae60', 'bold'), + 'string': format('#da4453'), + 'string2': format('#da4453'), + 'comment': format('#7f8c8d', 'italic'), + 'self': format('#3daee9'), + 'numbers': format('#f67400'), + 'background' : format('#232629'), + 'foreground' : format('#eff0f1'), + } + + def __getitem__(self, key): + return self.STYLES[key] + +class BreezeLightSyntaxStyle(object): + + """ Based on KDE Breeze widget style """ + # A light syntax style. + STYLES = { + 'keyword': format('#31363b'), + 'operator': format('#31363b'), + 'brace': format('#31363b'), + 'defclass': format('#27ae60', 'bold'), + 'string': format('#da4453'), + 'string2': format('#da4453'), + 'comment': format('#7f8c8d', 'italic'), + 'self': format('#3daee9'), + 'numbers': format('#f67400'), + 'background' : format('#fcfcfc'), + 'foreground' : format('#31363b'), + } + + def __getitem__(self, key): + return self.STYLES[key] + +class BlenderSyntaxStyle(object): + + """ Based on KDE Breeze widget style """ + # A light syntax style. + STYLES = { + 'keyword': format('#606002'), + 'operator': format('#4c4c4c'), + 'brace': format('#4c4c4c'), + 'defclass': format('#000000'), + 'string': format('#650202'), + 'string2': format('#650202'), + 'comment': format('#006432'), + 'self': format('#000000'), + 'numbers': format('#0000c8'), + 'background' : format('#999999'), + 'foreground' : format('#000000'), + } + + def __getitem__(self, key): + return self.STYLES[key] + +class SolarizedDarkSyntaxStyle(object): + + """ Based on http://ethanschoonover.com/solarized """ + # A dark syntax style. + STYLES = { + 'keyword': format('#6b9500'), + 'operator': format('#839496'), + 'brace': format('#839496'), + 'defclass': format('#248bd2', 'bold'), + 'string': format('#29a198'), + 'string2': format('#29a198'), + 'comment': format('#586e75', 'italic'), + 'self': format('#248bd2'), + 'numbers': format('#b58900'), + 'background' : format('#002a35'), + 'foreground' : format('#839496'), + } + + def __getitem__(self, key): + return self.STYLES[key] + +class SolarizedLightSyntaxStyle(object): + + """ Based on http://ethanschoonover.com/solarized """ + # A light syntax style. + STYLES = { + 'keyword': format('#6b9500'), + 'operator': format('#839496'), + 'brace': format('#839496'), + 'defclass': format('#248bd2', 'bold'), + 'string': format('#29a198'), + 'string2': format('#29a198'), + 'comment': format('#586e75', 'italic'), + 'self': format('#248bd2'), + 'numbers': format('#b58900'), + 'background' : format('#fdf6e3'), + 'foreground' : format('#839496'), + } + + def __getitem__(self, key): + return self.STYLES[key]