Skip to content

Commit d5f58e0

Browse files
committed
feat(theme): apply dark mode to graphs
Add _styleAxes() for matplotlib dark/light mode styling. Apply Colors to graph canvas, control panel, vector picker. Update style pickers and line style icons for theme awareness.
1 parent 2f3b60d commit d5f58e0

File tree

6 files changed

+48
-7
lines changed

6 files changed

+48
-7
lines changed

graphs/gui/canvasPanel.py

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131

3232

3333
from graphs.style import BASE_COLORS, LIGHTNESSES, STYLES, hsl_to_hsv
34+
from gui.utils.colors import Colors
35+
from gui.utils.dark import isDark
3436
from gui.utils.numberFormatter import roundToPrec
3537

3638

@@ -84,7 +86,7 @@ def __init__(self, graphFrame, parent):
8486
mainSizer = wx.BoxSizer(wx.VERTICAL)
8587

8688
self.figure = Figure(figsize=(5, 3), tight_layout={'pad': 1.08})
87-
rgbtuple = wx.SystemSettings.GetColour(wx.SYS_COLOUR_BTNFACE).Get()
89+
rgbtuple = Colors.buttonFace().Get()
8890
clr = [c / 255. for c in rgbtuple]
8991
self.figure.set_facecolor(clr)
9092
self.figure.set_edgecolor(clr)
@@ -93,6 +95,10 @@ def __init__(self, graphFrame, parent):
9395
self.canvas.mpl_connect('button_press_event', self.OnMplCanvasClick)
9496
self.subplot = self.figure.add_subplot(111)
9597
self.subplot.grid(True)
98+
99+
# Style axes for dark mode
100+
self._styleAxes()
101+
96102
mainSizer.Add(self.canvas, 1, wx.EXPAND | wx.ALL, 0)
97103

98104
self.SetSizer(mainSizer)
@@ -104,6 +110,7 @@ def __init__(self, graphFrame, parent):
104110
def draw(self, accurateMarks=True):
105111
self.subplot.clear()
106112
self.subplot.grid(True)
113+
self._styleAxes() # Re-apply styling after clear
107114
allXs = set()
108115
allYs = set()
109116
plotData = {}
@@ -294,6 +301,32 @@ def unmarkX(self):
294301
self.xMark = None
295302
self.draw()
296303

304+
def _styleAxes(self):
305+
"""Style the matplotlib axes for dark/light mode."""
306+
if isDark():
307+
textColor = '#DCDCDC' # Light gray text for dark mode
308+
axisColor = '#888888' # Gray for axis lines
309+
else:
310+
textColor = '#000000' # Black text for light mode
311+
axisColor = '#000000' # Black for axis lines
312+
313+
# Set background color for the plot area
314+
bgColor = Colors.windowBackground().Get()
315+
bgColorNorm = [c / 255. for c in bgColor]
316+
self.subplot.set_facecolor(bgColorNorm)
317+
318+
# Style axis spines (the lines around the plot)
319+
for spine in self.subplot.spines.values():
320+
spine.set_color(axisColor)
321+
322+
# Style tick labels and axis labels
323+
self.subplot.tick_params(colors=textColor, labelcolor=textColor)
324+
self.subplot.xaxis.label.set_color(textColor)
325+
self.subplot.yaxis.label.set_color(textColor)
326+
327+
# Style grid
328+
self.subplot.grid(True, color=axisColor, alpha=0.3)
329+
297330
@staticmethod
298331
def _getLimits(vals, minExtra=0, maxExtra=0):
299332
minVal = min(vals, default=0)

graphs/gui/ctrlPanel.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
from gui.bitmap_loader import BitmapLoader
2727
from gui.contextMenu import ContextMenu
28+
from gui.utils.colors import ThemedPanel, Colors
2829
from gui.utils.inputs import FloatBox, FloatRangeBox
2930
from service.const import GraphCacheCleanupReason
3031
from service.fit import Fit
@@ -37,7 +38,7 @@
3738
_t = wx.GetTranslation
3839

3940

40-
class GraphControlPanel(wx.Panel):
41+
class GraphControlPanel(ThemedPanel):
4142

4243
def __init__(self, graphFrame, parent):
4344
super().__init__(parent)
@@ -56,6 +57,7 @@ def __init__(self, graphFrame, parent):
5657
yText = wx.StaticText(self, wx.ID_ANY, _t('Axis Y:'))
5758
ySubSelectionSizer.Add(yText, 0, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, 5)
5859
self.ySubSelection = wx.Choice(self, wx.ID_ANY)
60+
Colors.styleInput(self.ySubSelection)
5961
self.ySubSelection.Bind(wx.EVT_CHOICE, self.OnYTypeUpdate)
6062
ySubSelectionSizer.Add(self.ySubSelection, 1, wx.EXPAND | wx.ALL, 0)
6163
commonOptsSizer.Add(ySubSelectionSizer, 0, wx.EXPAND | wx.ALL, 0)
@@ -64,6 +66,7 @@ def __init__(self, graphFrame, parent):
6466
xText = wx.StaticText(self, wx.ID_ANY, _t('Axis X:'))
6567
xSubSelectionSizer.Add(xText, 0, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, 5)
6668
self.xSubSelection = wx.Choice(self, wx.ID_ANY)
69+
Colors.styleInput(self.xSubSelection)
6770
self.xSubSelection.Bind(wx.EVT_CHOICE, self.OnXTypeUpdate)
6871
xSubSelectionSizer.Add(self.xSubSelection, 1, wx.EXPAND | wx.ALL, 0)
6972
commonOptsSizer.Add(xSubSelectionSizer, 0, wx.EXPAND | wx.TOP, 5)

graphs/gui/frame.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
from graphs.events import RESIST_MODE_CHANGED
3030
from gui.auxWindow import AuxiliaryFrame
3131
from gui.bitmap_loader import BitmapLoader
32+
from gui.utils.colors import Colors
3233
from service.const import GraphCacheCleanupReason
3334
from service.settings import GraphSettings
3435
from . import canvasPanel
@@ -58,6 +59,7 @@ def __init__(self, parent, includeHidden=False):
5859

5960
# Layout - graph selector
6061
self.graphSelection = wx.Choice(self, wx.ID_ANY, style=0)
62+
Colors.styleInput(self.graphSelection)
6163
self.graphSelection.Bind(wx.EVT_CHOICE, self.OnGraphSwitched)
6264
mainSizer.Add(self.graphSelection, 0, wx.EXPAND)
6365

graphs/gui/stylePickers.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
from graphs.style import BASE_COLORS, LIGHTNESSES, STYLES
2525
from gui.bitmap_loader import BitmapLoader
26+
from gui.utils.colors import Colors
2627
from service.const import GraphLightness
2728

2829

@@ -32,7 +33,7 @@ def __init__(self, parent, wrapper):
3233
super().__init__(parent, flags=wx.BORDER_SIMPLE)
3334
self.wrapper = wrapper
3435

35-
self.SetBackgroundColour(wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOW))
36+
self.SetBackgroundColour(Colors.windowBackground())
3637
sizer = wx.BoxSizer(wx.VERTICAL)
3738

3839
grid = wx.GridSizer(self.nrows, self.ncols, 0, 0)

graphs/gui/vector.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import wx
2525

2626
from eos.utils.float import floatUnerr
27+
from gui.utils.colors import Colors
2728

2829

2930
class VectorPicker(wx.Window):
@@ -114,13 +115,13 @@ def Draw(self, dc):
114115
width, height = self.GetScaledClientSize()
115116
if not width or not height:
116117
return
117-
dc.SetBackground(wx.Brush(self.GetBackgroundColour(), wx.BRUSHSTYLE_SOLID))
118+
dc.SetBackground(wx.Brush(Colors.buttonFace(), wx.BRUSHSTYLE_SOLID))
118119
dc.Clear()
119-
dc.SetTextForeground(wx.Colour(0))
120+
dc.SetTextForeground(Colors.text())
120121
dc.SetFont(self._font)
121122

122123
radius = min(width, height) / 2 - 2
123-
dc.SetBrush(wx.WHITE_BRUSH)
124+
dc.SetBrush(wx.Brush(Colors.windowBackground()))
124125
dc.DrawCircle(round(radius + 2), round(radius + 2), round(radius))
125126
a = math.radians(self._angle + self._offset)
126127
x = math.cos(a) * radius

graphs/style.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
# noinspection PyPackageRequirements
2424
import wx
2525

26+
from gui.utils.colors import Colors
2627
from service.const import GraphColor, GraphLightness, GraphLineStyle
2728

2829
ColorData = namedtuple('ColorData', ('hsl', 'name', 'iconName'))
@@ -41,7 +42,7 @@ def __init__(self, name, iconNamePrefix, mplSpec):
4142
def iconName(self):
4243
# Get lightness out of RGB color, see following link for math:
4344
# https://www.niwa.nu/2013/05/math-behind-colorspace-conversions-rgb-hsl/
44-
r, g, b, a = (c / 255 for c in wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOW))
45+
r, g, b, a = (c / 255 for c in Colors.windowBackground())
4546
l = (max(r, g, b) + min (r, g, b)) / 2
4647
suffix = '_black' if l > 0.3 else '_white'
4748
return '{}{}'.format(self._iconNamePrefix, suffix)

0 commit comments

Comments
 (0)