forked from IPKM/nmreval
BUGFIX: VFT;
change to src layout
This commit is contained in:
235
src/gui_qt/lib/delegates.py
Normal file
235
src/gui_qt/lib/delegates.py
Normal file
@ -0,0 +1,235 @@
|
||||
import re
|
||||
|
||||
from nmreval.lib.colors import BaseColor, Colors
|
||||
from nmreval.lib.lines import LineStyle
|
||||
from nmreval.lib.symbols import SymbolStyle, make_symbol_pixmap
|
||||
|
||||
from ..Qt import QtWidgets, QtGui, QtCore
|
||||
|
||||
|
||||
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:
|
||||
self.setCurrentIndex(i)
|
||||
break
|
||||
|
||||
def populateList(self):
|
||||
for i, colorName in enumerate(Colors):
|
||||
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())
|
Reference in New Issue
Block a user