@@ -53,6 +53,8 @@ def __init__(
53
53
) # type: ignore[no-untyped-call]
54
54
self ._replace_toolbar_icons ()
55
55
# callback to update when napari theme changed
56
+ # TODO: this isn't working completely (see issue #140)
57
+ # most of our styling respects the theme change but not all
56
58
self .viewer .events .theme .connect (self ._on_theme_change )
57
59
58
60
self .setLayout (QVBoxLayout ())
@@ -77,22 +79,22 @@ def apply_napari_colorscheme(self, ax: Axes) -> None:
77
79
"""Apply napari-compatible colorscheme to an Axes."""
78
80
# get the foreground colours from current theme
79
81
theme = napari .utils .theme .get_theme (self .viewer .theme , as_dict = False )
80
- fg = theme .foreground .as_hex () # fg is a muted contrast to bg
81
- tx = theme .text .as_hex () # text is high contrast to bg
82
+ fg_colour = theme .foreground .as_hex () # fg is a muted contrast to bg
83
+ text_colour = theme .text .as_hex () # text is high contrast to bg
82
84
83
85
# changing color of axes background to transparent
84
86
ax .set_facecolor ("none" )
85
87
86
88
# changing colors of all axes
87
89
for spine in ax .spines :
88
- ax .spines [spine ].set_color (fg )
90
+ ax .spines [spine ].set_color (fg_colour )
89
91
90
- ax .xaxis .label .set_color (tx )
91
- ax .yaxis .label .set_color (tx )
92
+ ax .xaxis .label .set_color (text_colour )
93
+ ax .yaxis .label .set_color (text_colour )
92
94
93
95
# changing colors of axes labels
94
- ax .tick_params (axis = "x" , colors = tx )
95
- ax .tick_params (axis = "y" , colors = tx )
96
+ ax .tick_params (axis = "x" , colors = text_colour )
97
+ ax .tick_params (axis = "y" , colors = text_colour )
96
98
97
99
def _on_theme_change (self ) -> None :
98
100
"""Update MPL toolbar and axis styling when `napari.Viewer.theme` is changed.
@@ -104,15 +106,24 @@ def _on_theme_change(self) -> None:
104
106
if self .figure .gca ():
105
107
self .apply_napari_colorscheme (self .figure .gca ())
106
108
109
+ def _theme_has_light_bg (self ) -> bool :
110
+ """
111
+ Does this theme have a light background?
112
+
113
+ Returns
114
+ -------
115
+ bool
116
+ True if theme's background colour has hsl lighter than 50%, False if darker.
117
+ """
118
+ theme = napari .utils .theme .get_theme (self .viewer .theme , as_dict = False )
119
+ _ , _ , bg_lightness = theme .background .as_hsl_tuple ()
120
+ return bg_lightness > 0.5
121
+
107
122
def _get_path_to_icon (self ) -> Path :
108
123
"""
109
124
Get the icons directory (which is theme-dependent).
110
125
"""
111
- # TODO: can make this more robust by doing some RGB tricks to figure out
112
- # whether white or black icons are going to be more visible given the
113
- # theme.background
114
- islight = self .viewer .theme == "light"
115
- if islight :
126
+ if self ._theme_has_light_bg ():
116
127
return ICON_ROOT / "black"
117
128
else :
118
129
return ICON_ROOT / "white"
0 commit comments