Show number of missing pilots in the UI.

https://github.com/dcs-liberation/dcs_liberation/issues/276
This commit is contained in:
Dan Albert
2021-05-26 15:53:41 -07:00
parent 4147d2f684
commit 9c2bad85d5
7 changed files with 166 additions and 156 deletions

122
qt_ui/delegates.py Normal file
View File

@@ -0,0 +1,122 @@
from contextlib import contextmanager
from typing import ContextManager, Optional
from PySide2.QtCore import QModelIndex, Qt, QSize
from PySide2.QtGui import QPainter, QFont, QFontMetrics, QIcon
from PySide2.QtWidgets import QStyledItemDelegate, QStyleOptionViewItem, QStyle
@contextmanager
def painter_context(painter: QPainter) -> ContextManager[None]:
try:
painter.save()
yield
finally:
painter.restore()
class TwoColumnRowDelegate(QStyledItemDelegate):
HMARGIN = 4
VMARGIN = 4
def __init__(self, rows: int, columns: int, font_size: int = 12) -> None:
if columns not in (1, 2):
raise ValueError(f"Only one or two columns may be used, not {columns}")
super().__init__()
self.font_size = font_size
self.rows = rows
self.columns = columns
def get_font(self, option: QStyleOptionViewItem) -> QFont:
font = QFont(option.font)
font.setPointSize(self.font_size)
return font
def text_for(self, index: QModelIndex, row: int, column: int) -> str:
raise NotImplementedError
def paint(
self, painter: QPainter, option: QStyleOptionViewItem, index: QModelIndex
) -> None:
# Draw the list item with all the default selection styling, but with an
# invalid index so text formatting is left to us.
super().paint(painter, option, QModelIndex())
rect = option.rect.adjusted(
self.HMARGIN, self.VMARGIN, -self.HMARGIN, -self.VMARGIN
)
with painter_context(painter):
painter.setFont(self.get_font(option))
icon: Optional[QIcon] = index.data(Qt.DecorationRole)
if icon is not None:
icon.paint(
painter,
rect,
Qt.AlignLeft | Qt.AlignVCenter,
self.icon_mode(option),
self.icon_state(option),
)
rect = rect.adjusted(self.icon_size(option).width() + self.HMARGIN, 0, 0, 0)
row_height = rect.height() / self.rows
for row in range(self.rows):
y = row_height * row
location = rect.adjusted(0, y, 0, y)
painter.drawText(location, Qt.AlignLeft, self.text_for(index, row, 0))
if self.columns == 2:
painter.drawText(
location, Qt.AlignRight, self.text_for(index, row, 1)
)
@staticmethod
def icon_mode(option: QStyleOptionViewItem) -> QIcon.Mode:
if not (option.state & QStyle.State_Enabled):
return QIcon.Disabled
elif option.state & QStyle.State_Selected:
return QIcon.Selected
elif option.state & QStyle.State_Active:
return QIcon.Active
return QIcon.Normal
@staticmethod
def icon_state(option: QStyleOptionViewItem) -> QIcon.State:
return QIcon.On if option.state & QStyle.State_Open else QIcon.Off
@staticmethod
def icon_size(option: QStyleOptionViewItem) -> QSize:
icon_size: Optional[QSize] = option.decorationSize
if icon_size is None:
return QSize(0, 0)
else:
return icon_size
def sizeHint(self, option: QStyleOptionViewItem, index: QModelIndex) -> QSize:
metrics = QFontMetrics(self.get_font(option))
widths = []
heights = []
icon_size = self.icon_size(option)
icon_width = 0
icon_height = 0
if icon_size.width():
icon_width = icon_size.width() + self.HMARGIN
if icon_size.height():
icon_height = icon_size.height() + self.VMARGIN
for row in range(self.rows):
width = 0
height = 0
for column in range(self.columns):
size = metrics.size(0, self.text_for(index, row, column))
width += size.width()
height = max(height, size.height())
widths.append(width)
heights.append(height)
return QSize(
icon_width + max(widths) + 2 * self.HMARGIN,
max(icon_height, sum(heights)) + 2 * self.VMARGIN,
)