gui: improve usability in dark mode (bug 1719424) (#1290)

This commit is contained in:
Kenneth Chew 2023-05-31 11:13:59 -04:00 коммит произвёл GitHub
Родитель 2911cbc8d4
Коммит 08255e7cde
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
9 изменённых файлов: 94 добавлений и 17 удалений

Двоичные данные
gui/icons/cross106_white.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 4.4 KiB

Двоичные данные
gui/icons/cutting10_white.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 4.6 KiB

Двоичные данные
gui/icons/letter52_white.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 4.8 KiB

Просмотреть файл

@ -1,7 +1,8 @@
from tempfile import mkdtemp
import mozfile
from PySide6.QtCore import QSettings, Slot
from PySide6.QtCore import QEvent, QSettings, Slot
from PySide6.QtGui import QIcon
from PySide6.QtWidgets import QMainWindow, QMessageBox
from mozregression import __version__ as mozregression_version
@ -11,6 +12,7 @@ from mozregui.global_prefs import change_prefs_dialog, get_prefs
from mozregui.report_delegate import ReportItemDelegate
from mozregui.single_runner import SingleBuildRunner
from mozregui.ui.mainwindow import Ui_MainWindow
from mozregui.utils import is_dark_mode_enabled
from mozregui.wizard import BisectionWizard, SingleRunWizard
ABOUT_TEXT = """\
@ -39,6 +41,7 @@ class MainWindow(QMainWindow):
MainWindow.INSTANCE = self
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self._update_palette()
self.bisect_runner = BisectRunner(self)
self.single_runner = SingleBuildRunner(self)
@ -101,6 +104,16 @@ class MainWindow(QMainWindow):
runner.start(*wizard.options())
def _update_palette(self):
if is_dark_mode_enabled():
self.ui.actionRun_a_single_build.setIcon(QIcon(":/s_white.png"))
self.ui.actionStart_a_new_bisection.setIcon(QIcon(":/cutting_white.png"))
self.ui.actionStop_the_bisection.setIcon(QIcon(":/stop_white.png"))
else:
self.ui.actionRun_a_single_build.setIcon(QIcon(":/s.png"))
self.ui.actionStart_a_new_bisection.setIcon(QIcon(":/cutting.png"))
self.ui.actionStop_the_bisection.setIcon(QIcon(":/stop.png"))
@Slot()
def start_bisection_wizard(self):
self._start_runner(BisectionWizard, self.bisect_runner)
@ -122,3 +135,10 @@ class MainWindow(QMainWindow):
@Slot()
def edit_global_prefs(self):
change_prefs_dialog(self)
def event(self, event: QEvent) -> bool:
if event.type() == QEvent.PaletteChange:
self._update_palette()
return True
return super().event(event)

Просмотреть файл

@ -3,14 +3,20 @@ from PySide6.QtGui import QColor, QDesktopServices
from PySide6.QtWidgets import QTableView, QTextBrowser
from mozregression.bisector import NightlyHandler
from mozregui.utils import is_dark_mode_enabled
# Custom colors
GRAY_WHITE = QColor(243, 243, 243)
DARK_GRAY = QColor(28, 28, 28)
VERDICT_TO_ROW_COLORS = {
"g": QColor(152, 251, 152), # light green
"b": QColor(250, 113, 113), # light red
"s": QColor(253, 248, 107), # light yellow
"r": QColor(225, 225, 225), # light gray
"g_dark": QColor(48, 209, 88), # green
"b_dark": QColor(255, 70, 58), # red
"s_dark": QColor(160, 90, 0), # yellow
"r_dark": QColor(45, 45, 45), # gray
}
@ -167,7 +173,12 @@ class ReportModel(QAbstractTableModel):
return item.status_text()
elif role == Qt.BackgroundRole:
if isinstance(item, StepItem) and item.verdict:
return VERDICT_TO_ROW_COLORS.get(str(item.verdict), GRAY_WHITE)
if is_dark_mode_enabled():
return VERDICT_TO_ROW_COLORS.get(str(item.verdict) + "_dark", DARK_GRAY)
else:
return VERDICT_TO_ROW_COLORS.get(str(item.verdict), GRAY_WHITE)
elif is_dark_mode_enabled():
return DARK_GRAY
else:
return GRAY_WHITE

Просмотреть файл

@ -1,5 +1,5 @@
from PySide6.QtCore import QRect, Qt, Signal
from PySide6.QtGui import QIcon, QPainter, QPixmap
from PySide6.QtCore import QEvent, QRect, Qt, Signal
from PySide6.QtGui import QIcon, QPainter, QPen, QPixmap
from PySide6.QtWidgets import (
QApplication,
QStyle,
@ -10,6 +10,7 @@ from PySide6.QtWidgets import (
from mozregui.report import VERDICT_TO_ROW_COLORS
from mozregui.ui.ask_verdict import Ui_AskVerdict
from mozregui.utils import is_dark_mode_enabled
VERDICTS = ("good", "bad", "skip", "retry", "other...")
@ -25,17 +26,7 @@ class AskVerdict(QWidget):
self.ui.setupUi(self)
# build verdict icons
if not AskVerdict.icons_cache:
for text in VERDICTS:
color = VERDICT_TO_ROW_COLORS.get(text[0])
pixmap = QPixmap(16, 16)
pixmap.fill(Qt.transparent)
if color:
painter = QPainter(pixmap)
painter.setPen(Qt.black)
painter.setBrush(color)
painter.drawEllipse(0, 0, 15, 15)
painter.end()
AskVerdict.icons_cache[text] = QIcon(pixmap)
self._build_icon_cache()
# set combo verdict
for text in ("other...", "skip", "retry"):
@ -51,6 +42,29 @@ class AskVerdict(QWidget):
self.ui.badVerdict.clicked.connect(self.on_good_bad_button_clicked)
self.ui.badVerdict.setIcon(AskVerdict.icons_cache["bad"])
def _build_icon_cache(self):
for text in VERDICTS:
if is_dark_mode_enabled():
color = VERDICT_TO_ROW_COLORS.get(text[0] + "_dark")
else:
color = VERDICT_TO_ROW_COLORS.get(text[0])
pixmap = QPixmap(16, 16)
pixmap.fill(Qt.transparent)
if color:
painter = QPainter(pixmap)
painter.setPen(QPen(self.palette().windowText().color()))
painter.setBrush(color)
painter.drawEllipse(0, 0, 15, 15)
painter.end()
AskVerdict.icons_cache[text] = QIcon(pixmap)
def _update_icons(self):
self.ui.goodVerdict.setIcon(AskVerdict.icons_cache["good"])
self.ui.badVerdict.setIcon(AskVerdict.icons_cache["bad"])
for i in range(self.ui.comboVerdict.count()):
text = str(self.ui.comboVerdict.itemText(i))
self.ui.comboVerdict.setItemIcon(i, AskVerdict.icons_cache[text])
def on_dropdown_item_activated(self):
self.delegate.got_verdict.emit(str(self.ui.comboVerdict.currentText())[0].lower())
self.emitted = True
@ -59,6 +73,13 @@ class AskVerdict(QWidget):
self.delegate.got_verdict.emit(str(self.sender().text())[0].lower())
self.emitted = True
def event(self, event: QEvent) -> bool:
if event.type() == QEvent.PaletteChange:
self._build_icon_cache()
self._update_icons()
return True
return super().event(event)
class ReportItemDelegate(QStyledItemDelegate):
got_verdict = Signal(str)

Просмотреть файл

@ -1,5 +1,5 @@
from PySide6.QtCore import Qt, Signal
from PySide6.QtGui import QBrush
from PySide6.QtCore import QEvent, Qt, Signal
from PySide6.QtGui import QBrush, QPen
from PySide6.QtWidgets import (
QDialog,
QGraphicsRectItem,
@ -53,8 +53,22 @@ class SkipChooserScene(QGraphicsScene):
self.mid_build = item
elif i in bounds:
item.setBrush(QBrush(Qt.lightGray))
pen = QPen(self.palette().windowText().color())
item.setPen(pen)
self.addItem(item)
def _update_palette(self):
for item in self.items():
pen = QPen(self.palette().windowText().color())
item.setPen(pen)
def event(self, event: QEvent) -> bool:
if event.type() == QEvent.PaletteChange:
self._update_palette()
return True
return super().event(event)
class SkipChooserView(QGraphicsView):
build_choosen = Signal()

Просмотреть файл

@ -1,4 +1,5 @@
from PySide6.QtCore import QDir
from PySide6.QtGui import QGuiApplication, QPalette
from PySide6.QtWidgets import (
QCompleter,
QFileDialog,
@ -85,3 +86,10 @@ class BuildSelection(QWidget):
raise DateFormatError(buildid, "Not a valid build id: `%s`")
elif currentw == self.ui.s_changeset:
return self.ui.changeset.text().strip()
def is_dark_mode_enabled():
"""
Return True if dark mode is being used.
"""
return QGuiApplication.palette().color(QPalette.Window).lightness() < 128

Просмотреть файл

@ -4,5 +4,8 @@
<file alias="stop.png">icons/cross106.png</file>
<file alias="cutting.png">icons/cutting10.png</file>
<file alias="s.png">icons/letter52.png</file>
<file alias="stop_white.png">icons/cross106_white.png</file>
<file alias="cutting_white.png">icons/cutting10_white.png</file>
<file alias="s_white.png">icons/letter52_white.png</file>
</qresource>
</RCC>