Skip to content

Commit

Permalink
gui: improve usability in dark mode (bug 1719424) (#1290)
Browse files Browse the repository at this point in the history
  • Loading branch information
kthchew authored May 31, 2023
1 parent 2911cbc commit 08255e7
Show file tree
Hide file tree
Showing 9 changed files with 94 additions and 17 deletions.
Binary file added gui/icons/cross106_white.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added gui/icons/cutting10_white.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added gui/icons/letter52_white.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
22 changes: 21 additions & 1 deletion gui/mozregui/mainwindow.py
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -11,6 +12,7 @@
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 = """\
Expand Down Expand Up @@ -39,6 +41,7 @@ def __init__(self):
MainWindow.INSTANCE = self
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self._update_palette()

self.bisect_runner = BisectRunner(self)
self.single_runner = SingleBuildRunner(self)
Expand Down Expand Up @@ -101,6 +104,16 @@ def _start_runner(self, wizard_class, runner):

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)
Expand All @@ -122,3 +135,10 @@ def show_about(self):
@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)
13 changes: 12 additions & 1 deletion gui/mozregui/report.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,20 @@
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
}


Expand Down Expand Up @@ -167,7 +173,12 @@ def data(self, index, role=Qt.DisplayRole):
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

Expand Down
47 changes: 34 additions & 13 deletions gui/mozregui/report_delegate.py
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -10,6 +10,7 @@

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...")

Expand All @@ -25,17 +26,7 @@ def __init__(self, parent, delegate):
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"):
Expand All @@ -51,6 +42,29 @@ def __init__(self, parent, delegate):
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
Expand All @@ -59,6 +73,13 @@ def on_good_bad_button_clicked(self):
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)
Expand Down
18 changes: 16 additions & 2 deletions gui/mozregui/skip_chooser.py
Original file line number Diff line number Diff line change
@@ -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,
Expand Down Expand Up @@ -53,8 +53,22 @@ def from_range(self, build_range):
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()
Expand Down
8 changes: 8 additions & 0 deletions gui/mozregui/utils.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from PySide6.QtCore import QDir
from PySide6.QtGui import QGuiApplication, QPalette
from PySide6.QtWidgets import (
QCompleter,
QFileDialog,
Expand Down Expand Up @@ -85,3 +86,10 @@ def get_value(self):
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
3 changes: 3 additions & 0 deletions gui/resources.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -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>

0 comments on commit 08255e7

Please sign in to comment.