Skip to content

Commit a4763c6

Browse files
parse icons for dark mode and avoid modification of toolbar bg
1 parent 2acd62c commit a4763c6

2 files changed

Lines changed: 81 additions & 4 deletions

File tree

src/PyMca5/PyMcaGui/plotting/PlotWindow.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -259,9 +259,6 @@ def _buildToolBar(self, kw=None):
259259
if kw is None:
260260
kw = {}
261261
self.toolBar = qt.QToolBar(self)
262-
if qt.QApplication.instance().palette().color(qt.QPalette.Text) == qt.QColor('white'):
263-
newColor = qt.QApplication.instance().palette().color(qt.QPalette.Light)
264-
self.toolBar.setStyleSheet("QToolBar { background-color: %s; }" % newColor.name())
265262
self.toolBarActionsDict = {}
266263
#Autoscale
267264
self._addToolButton(self.zoomResetIcon,

src/PyMca5/PyMcaGui/plotting/PyMca_Icons.py

Lines changed: 81 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
__copyright__ = "European Synchrotron Radiation Facility, Grenoble, France"
3030

3131
import logging
32+
import re
3233
import sys
3334

3435
if sys.version_info < (3, ):
@@ -3734,6 +3735,71 @@
37343735
}
37353736

37363737

3738+
DARK_MODE_TABLE = [
3739+
"average16", "derive", "fit", "logx", "logy", "normal",
3740+
"normalize16", "peak", "peakreset", "peaksearch", "roi",
3741+
"roireset", "rotate_left", "rotate_right", "smooth",
3742+
"xauto", "yauto", "ymintozero", "filesave"
3743+
]
3744+
3745+
3746+
def _parse_xpm_color(color_spec):
3747+
"""Parse an XPM color specification into an (r, g, b) tuple.
3748+
3749+
Returns None if color is unknown.
3750+
"""
3751+
spec = color_spec.strip()
3752+
lower = spec.lower()
3753+
if lower == 'none':
3754+
return None
3755+
if spec.startswith('#'):
3756+
h = spec[1:]
3757+
# hex colors
3758+
if len(h) == 6:
3759+
return (int(h[0:2], 16), int(h[2:4], 16), int(h[4:6], 16))
3760+
# short hex colors
3761+
if len(h) == 3:
3762+
return (int(h[0], 16) * 17, int(h[1], 16) * 17,
3763+
int(h[2], 16) * 17)
3764+
# named colors, no reason to check red, yellow, etc as they are saturated
3765+
if lower == "black":
3766+
return (0, 0, 0)
3767+
elif lower == "white":
3768+
return (255, 255, 255)
3769+
else:
3770+
return None
3771+
3772+
3773+
def _to_reverse_color(r, g, b):
3774+
"""Return True if the color need to be reversed for dark mode.
3775+
"""
3776+
# not to reverse saturated colours
3777+
if (max(r, g, b) - min(r, g, b)) > 40:
3778+
return False
3779+
# one can check (r + g + b) < 3*128 but then outlines could look bad
3780+
return True
3781+
3782+
3783+
def _adapt_xpm_for_dark_mode(xpm_data):
3784+
"""Return a copy of *xpm_data* with some colours inverted.
3785+
3786+
"""
3787+
result = list(xpm_data)
3788+
xpm_info = result[0].split()
3789+
number_of_colors = int(xpm_info[2])
3790+
for i in range(1, 1 + number_of_colors):
3791+
symbol = result[i].split(" c ")[0]
3792+
rgb_raw = result[i].split(" c ")[1]
3793+
rgb = _parse_xpm_color(rgb_raw)
3794+
if rgb is None:
3795+
continue
3796+
r, g, b = _parse_xpm_color(rgb_raw)
3797+
if _to_reverse_color(r, g, b):
3798+
result[i] = "%s c #%02x%02x%02x" \
3799+
% (symbol, 255 - r, 255 - g, 255 - b)
3800+
return result
3801+
3802+
37373803
class _PatchedIconDict(MutableMapping):
37383804
"""IconDict that patches some legacy icons with new
37393805
silx icons, when available.
@@ -3749,6 +3815,7 @@ class _PatchedIconDict(MutableMapping):
37493815
def __init__(self, *args, **kw):
37503816
self._unpatched_icons = dict(*args, **kw)
37513817
self.__initialized = False
3818+
self._dark = {}
37523819

37533820
def __iter__(self):
37543821
for key in self._unpatched_icons:
@@ -3778,6 +3845,19 @@ def __getitem__(self, key):
37783845

37793846
if key not in self._unpatched_icons:
37803847
raise KeyError("Unknown icon '%s'" % key)
3848+
3849+
# even if it is dark mode but text is not white then black can probably be used
3850+
if self._qt.QApplication.instance().palette().color(self._qt.QPalette.Text) == self._qt.QColor('white'):
3851+
from PyMca5.PyMcaGui.plotting.Silx_Icons import IconDict as _silx_xpm
3852+
if key in DARK_MODE_TABLE:
3853+
silx_key = TRANSLATION_TABLE.get(key)
3854+
if silx_key:
3855+
xpm = _silx_xpm.get(silx_key)
3856+
else:
3857+
xpm = self._unpatched_icons.get(key)
3858+
self._dark[key] = _adapt_xpm_for_dark_mode(xpm)
3859+
return self._dark[key]
3860+
37813861

37823862
if key not in TRANSLATION_TABLE:
37833863
_logger.debug("Using legacy icon '%s' because there is no "
@@ -3825,7 +3905,7 @@ def __setitem__(self, key, item):
38253905

38263906

38273907
IconDict = _PatchedIconDict(IconDict0)
3828-
3908+
# IconDict = IconDict0
38293909

38303910
def change_icons(plot):
38313911
"""Replace some of the silx icons with PyMca icons.

0 commit comments

Comments
 (0)