1
0
forked from IPKM/nmreval
nmreval/nmreval/gui_qt/lib/delegates.py

235 lines
8.0 KiB
Python
Raw Normal View History

2022-03-08 09:27:40 +00:00
import re
from ..Qt import QtWidgets, QtGui, QtCore
from ...lib.colors import BaseColor, Colors
2022-03-08 09:27:40 +00:00
from ...lib.lines import LineStyle
from ...lib.symbols import SymbolStyle, make_symbol_pixmap
class PropertyDelegate(QtWidgets.QStyledItemDelegate):
def paint(self, painter: QtGui.QPainter, options: QtWidgets.QStyleOptionViewItem, idx: QtCore.QModelIndex):
r = idx.data(QtCore.Qt.DisplayRole)
if r is not None:
if isinstance(r, BaseColor):
painter.save()
c = QtGui.QColor(*r.value)
rect = options.rect
painter.fillRect(rect, QtGui.QBrush(c))
painter.restore()
elif isinstance(r, LineStyle):
painter.save()
pen = QtGui.QPen()
pal = QtGui.QGuiApplication.palette()
pen.setColor(pal.color(QtGui.QPalette.Text))
pen.setWidth(2)
pen.setStyle(r.value)
pen.setCapStyle(QtCore.Qt.RoundCap)
painter.setPen(pen)
rect = options.rect
rect.adjust(5, 0, -5, 0)
mid = (rect.bottom()+rect.top()) / 2
painter.drawLine(rect.left(), mid, rect.right(), mid)
painter.restore()
elif isinstance(r, SymbolStyle):
painter.save()
pen = QtGui.QPen()
pal = QtGui.QGuiApplication.palette()
pen.setColor(pal.color(QtGui.QPalette.Text))
painter.setPen(pen)
pm = make_symbol_pixmap(r)
painter.drawPixmap(options.rect.topLeft()+QtCore.QPoint(3, (options.rect.height()-pm.height())/2), pm)
style = QtWidgets.QApplication.style()
text_rect = style.subElementRect(QtWidgets.QStyle.SE_ItemViewItemText, options, None)
text_rect.adjust(5+pm.width(), 0, 0, 0)
painter.drawText(text_rect, options.displayAlignment, r.name)
painter.restore()
else:
super().paint(painter, options, idx)
def createEditor(self, parent: QtWidgets.QWidget,
options: QtWidgets.QStyleOptionViewItem, idx: QtCore.QModelIndex) -> QtWidgets.QWidget:
data = idx.data()
if isinstance(data, BaseColor):
editor = ColorListEditor(parent)
elif isinstance(data, LineStyle):
editor = LineStyleEditor(parent)
elif isinstance(data, SymbolStyle):
editor = SymbolStyleEditor(parent)
elif isinstance(data, float):
editor = SpinBoxEditor(parent)
else:
editor = super().createEditor(parent, options, idx)
return editor
def setEditorData(self, editor: QtWidgets.QWidget, idx: QtCore.QModelIndex):
data = idx.data()
if isinstance(data, (BaseColor, LineStyle, SymbolStyle)):
editor.value = data
else:
super().setEditorData(editor, idx)
def setModelData(self, editor: QtWidgets.QWidget, model: QtCore.QAbstractItemModel, idx: QtCore.QModelIndex):
data = idx.data()
if isinstance(data, (BaseColor, LineStyle, SymbolStyle)):
model.setData(idx, editor.value)
else:
super().setModelData(editor, model, idx)
class ColorListEditor(QtWidgets.QComboBox):
def __init__(self, parent=None):
super().__init__(parent)
self.populateList()
@QtCore.pyqtProperty(BaseColor, user=True)
def value(self):
return self.itemData(self.currentIndex())
@value.setter
def value(self, val):
for i in range(self.count()):
if val.name == self.itemData(i).name:
2022-03-08 09:27:40 +00:00
self.setCurrentIndex(i)
break
def populateList(self):
for i, colorName in enumerate(Colors):
2022-03-08 09:27:40 +00:00
color = QtGui.QColor(*colorName.value)
self.insertItem(i, colorName.name)
self.setItemData(i, colorName)
px = QtGui.QPixmap(self.iconSize())
px.fill(color)
self.setItemData(i, QtGui.QIcon(px), QtCore.Qt.DecorationRole)
class SpinBoxEditor(QtWidgets.QDoubleSpinBox):
def __init__(self, parent=None):
super().__init__(parent)
self.setValue(1.0)
self.setSingleStep(0.1)
self.setDecimals(1)
@QtCore.pyqtProperty(float, user=True)
def value(self):
return super().value()
@value.setter
def value(self, val):
super().setValue(val)
class LineStyleEditor(QtWidgets.QComboBox):
def __init__(self, parent=None):
super().__init__(parent=parent)
self.setItemDelegate(LineStyleDelegate())
self.populate()
@QtCore.pyqtProperty(int, user=True)
def value(self):
return self.itemData(self.currentIndex())
@value.setter
def value(self, val):
for i in range(self.count()):
if val == self.itemData(i):
self.setCurrentIndex(i)
break
def populate(self):
for i, style in enumerate(LineStyle):
self.insertItem(i, re.sub(r'([A-Z])', r' \g<1>', style.name))
self.setItemData(i, style)
def paintEvent(self, evt: QtGui.QPaintEvent):
if self.currentData() is not None:
painter = QtWidgets.QStylePainter(self)
opt = QtWidgets.QStyleOptionComboBox()
self.initStyleOption(opt)
painter.drawComplexControl(QtWidgets.QStyle.CC_ComboBox, opt)
pen = QtGui.QPen()
pal = QtGui.QGuiApplication.palette()
pen.setColor(pal.color(QtGui.QPalette.Text))
pen.setWidth(2)
pen.setStyle(self.currentData().value)
pen.setCapStyle(QtCore.Qt.RoundCap)
painter.setPen(pen)
rect = painter.style().subControlRect(QtWidgets.QStyle.CC_ComboBox,
opt, QtWidgets.QStyle.SC_ComboBoxEditField, None)
rect.adjust(+10, 0, -10, 0)
mid = (rect.bottom() + rect.top()) / 2
painter.drawLine(rect.left(), mid, rect.right(), mid)
painter.end()
else:
super().paintEvent(evt)
class LineStyleDelegate(QtWidgets.QStyledItemDelegate):
def paint(self, painter, option, index):
data = index.data(QtCore.Qt.UserRole)
if data is not None:
pen = QtGui.QPen()
pal = QtGui.QGuiApplication.palette()
pen.setColor(pal.color(QtGui.QPalette.Text))
pen.setWidth(2)
pen.setStyle(data.value)
pen.setCapStyle(QtCore.Qt.RoundCap)
painter.setPen(pen)
rect = option.rect
rect.adjust(+10, 0, -10, 0)
mid = (rect.bottom()+rect.top()) / 2
painter.drawLine(rect.left(), mid, rect.right(), mid)
else:
QtWidgets.QStyledItemDelegate.paint(self, painter, option, index)
class SymbolStyleEditor(QtWidgets.QComboBox):
def __init__(self, parent=None):
super().__init__(parent=parent)
self.populate()
@QtCore.pyqtProperty(SymbolStyle, user=True)
def value(self):
return self.itemData(self.currentIndex())
@value.setter
def value(self, val):
for i in range(self.count()):
if val == self.itemData(i):
self.setCurrentIndex(i)
break
def populate(self):
for i, s in enumerate(SymbolStyle):
self.insertItem(i, re.sub(r'([A-Z])', r' \g<1>', s.name))
self.setItemData(i, s)
self.setItemData(i, make_symbol_pixmap(s), QtCore.Qt.DecorationRole)
class HeaderDelegate(QtWidgets.QStyledItemDelegate):
def paint(self, painter: QtGui.QPainter, option: QtWidgets.QStyleOptionViewItem, index: QtCore.QModelIndex):
header_option = QtWidgets.QStyleOptionHeader()
header_option.rect = option.rect
style = QtWidgets.QApplication.style()
style.drawControl(QtWidgets.QStyle.CE_HeaderSection, header_option, painter)
if option.state & QtWidgets.QStyle.State_Selected:
painter.fillRect(option.rect, option.palette.highlight())