Skip to content
Draft
35 changes: 34 additions & 1 deletion graphs/gui/canvasPanel.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@


from graphs.style import BASE_COLORS, LIGHTNESSES, STYLES, hsl_to_hsv
from gui.utils.themes import Themes
from gui.utils.dark import isDark
from gui.utils.numberFormatter import roundToPrec


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

self.figure = Figure(figsize=(5, 3), tight_layout={'pad': 1.08})
rgbtuple = wx.SystemSettings.GetColour(wx.SYS_COLOUR_BTNFACE).Get()
rgbtuple = Themes.buttonFace().Get()
clr = [c / 255. for c in rgbtuple]
self.figure.set_facecolor(clr)
self.figure.set_edgecolor(clr)
Expand All @@ -93,6 +95,10 @@ def __init__(self, graphFrame, parent):
self.canvas.mpl_connect('button_press_event', self.OnMplCanvasClick)
self.subplot = self.figure.add_subplot(111)
self.subplot.grid(True)

# Style axes for dark mode
self._styleAxes()

mainSizer.Add(self.canvas, 1, wx.EXPAND | wx.ALL, 0)

self.SetSizer(mainSizer)
Expand All @@ -104,6 +110,7 @@ def __init__(self, graphFrame, parent):
def draw(self, accurateMarks=True):
self.subplot.clear()
self.subplot.grid(True)
self._styleAxes() # Re-apply styling after clear
allXs = set()
allYs = set()
plotData = {}
Expand Down Expand Up @@ -294,6 +301,32 @@ def unmarkX(self):
self.xMark = None
self.draw()

def _styleAxes(self):
"""Style the matplotlib axes for dark/light mode."""
if isDark():
textColor = '#DCDCDC' # Light gray text for dark mode
axisColor = '#888888' # Gray for axis lines
else:
textColor = '#000000' # Black text for light mode
axisColor = '#000000' # Black for axis lines

# Set background color for the plot area
bgColor = Themes.windowBackground().Get()
bgColorNorm = [c / 255. for c in bgColor]
self.subplot.set_facecolor(bgColorNorm)

# Style axis spines (the lines around the plot)
for spine in self.subplot.spines.values():
spine.set_color(axisColor)

# Style tick labels and axis labels
self.subplot.tick_params(colors=textColor, labelcolor=textColor)
self.subplot.xaxis.label.set_color(textColor)
self.subplot.yaxis.label.set_color(textColor)

# Style grid
self.subplot.grid(True, color=axisColor, alpha=0.3)

@staticmethod
def _getLimits(vals, minExtra=0, maxExtra=0):
minVal = min(vals, default=0)
Expand Down
5 changes: 4 additions & 1 deletion graphs/gui/ctrlPanel.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

from gui.bitmap_loader import BitmapLoader
from gui.contextMenu import ContextMenu
from gui.utils.themes import ThemedPanel, Themes
from gui.utils.inputs import FloatBox, FloatRangeBox
from service.const import GraphCacheCleanupReason
from service.fit import Fit
Expand All @@ -37,7 +38,7 @@
_t = wx.GetTranslation


class GraphControlPanel(wx.Panel):
class GraphControlPanel(ThemedPanel):

def __init__(self, graphFrame, parent):
super().__init__(parent)
Expand All @@ -56,6 +57,7 @@ def __init__(self, graphFrame, parent):
yText = wx.StaticText(self, wx.ID_ANY, _t('Axis Y:'))
ySubSelectionSizer.Add(yText, 0, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, 5)
self.ySubSelection = wx.Choice(self, wx.ID_ANY)
Themes.styleInput(self.ySubSelection)
self.ySubSelection.Bind(wx.EVT_CHOICE, self.OnYTypeUpdate)
ySubSelectionSizer.Add(self.ySubSelection, 1, wx.EXPAND | wx.ALL, 0)
commonOptsSizer.Add(ySubSelectionSizer, 0, wx.EXPAND | wx.ALL, 0)
Expand All @@ -64,6 +66,7 @@ def __init__(self, graphFrame, parent):
xText = wx.StaticText(self, wx.ID_ANY, _t('Axis X:'))
xSubSelectionSizer.Add(xText, 0, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, 5)
self.xSubSelection = wx.Choice(self, wx.ID_ANY)
Themes.styleInput(self.xSubSelection)
self.xSubSelection.Bind(wx.EVT_CHOICE, self.OnXTypeUpdate)
xSubSelectionSizer.Add(self.xSubSelection, 1, wx.EXPAND | wx.ALL, 0)
commonOptsSizer.Add(xSubSelectionSizer, 0, wx.EXPAND | wx.TOP, 5)
Expand Down
2 changes: 2 additions & 0 deletions graphs/gui/frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
from graphs.events import RESIST_MODE_CHANGED
from gui.auxWindow import AuxiliaryFrame
from gui.bitmap_loader import BitmapLoader
from gui.utils.themes import Themes
from service.const import GraphCacheCleanupReason
from service.settings import GraphSettings
from . import canvasPanel
Expand Down Expand Up @@ -58,6 +59,7 @@ def __init__(self, parent, includeHidden=False):

# Layout - graph selector
self.graphSelection = wx.Choice(self, wx.ID_ANY, style=0)
Themes.styleInput(self.graphSelection)
self.graphSelection.Bind(wx.EVT_CHOICE, self.OnGraphSwitched)
mainSizer.Add(self.graphSelection, 0, wx.EXPAND)

Expand Down
3 changes: 2 additions & 1 deletion graphs/gui/stylePickers.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

from graphs.style import BASE_COLORS, LIGHTNESSES, STYLES
from gui.bitmap_loader import BitmapLoader
from gui.utils.themes import Themes
from service.const import GraphLightness


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

self.SetBackgroundColour(wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOW))
self.SetBackgroundColour(Themes.windowBackground())
sizer = wx.BoxSizer(wx.VERTICAL)

grid = wx.GridSizer(self.nrows, self.ncols, 0, 0)
Expand Down
7 changes: 4 additions & 3 deletions graphs/gui/vector.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import wx

from eos.utils.float import floatUnerr
from gui.utils.themes import Themes


class VectorPicker(wx.Window):
Expand Down Expand Up @@ -114,13 +115,13 @@ def Draw(self, dc):
width, height = self.GetScaledClientSize()
if not width or not height:
return
dc.SetBackground(wx.Brush(self.GetBackgroundColour(), wx.BRUSHSTYLE_SOLID))
dc.SetBackground(wx.Brush(Themes.buttonFace(), wx.BRUSHSTYLE_SOLID))
dc.Clear()
dc.SetTextForeground(wx.Colour(0))
dc.SetTextForeground(Themes.text())
dc.SetFont(self._font)

radius = min(width, height) / 2 - 2
dc.SetBrush(wx.WHITE_BRUSH)
dc.SetBrush(wx.Brush(Themes.windowBackground()))
dc.DrawCircle(round(radius + 2), round(radius + 2), round(radius))
a = math.radians(self._angle + self._offset)
x = math.cos(a) * radius
Expand Down
3 changes: 2 additions & 1 deletion graphs/style.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
# noinspection PyPackageRequirements
import wx

from gui.utils.themes import Themes
from service.const import GraphColor, GraphLightness, GraphLineStyle

ColorData = namedtuple('ColorData', ('hsl', 'name', 'iconName'))
Expand All @@ -41,7 +42,7 @@ def __init__(self, name, iconNamePrefix, mplSpec):
def iconName(self):
# Get lightness out of RGB color, see following link for math:
# https://www.niwa.nu/2013/05/math-behind-colorspace-conversions-rgb-hsl/
r, g, b, a = (c / 255 for c in wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOW))
r, g, b, a = (c / 255 for c in Themes.windowBackground())
l = (max(r, g, b) + min (r, g, b)) / 2
suffix = '_black' if l > 0.3 else '_white'
return '{}{}'.format(self._iconNamePrefix, suffix)
Expand Down
7 changes: 6 additions & 1 deletion gui/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
import sys
from logbook import Logger
pyfalog = Logger(__name__)
from service.settings import LocaleSettings
from service.settings import LocaleSettings, ThemeSettings
from gui.utils.dark import enableWindowsDarkModeSupport


class PyfaApp(wx.App):
Expand All @@ -16,6 +17,10 @@ def OnInit(self):
# Name for my application.
self.appName = "pyfa"

# Initialize theme settings early so isDark() works correctly
ThemeSettings.getInstance()
enableWindowsDarkModeSupport()

#------------

# # Simplified init method.
Expand Down
7 changes: 4 additions & 3 deletions gui/attribute_gauge.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import wx

from gui.utils import anim_effects
from gui.utils.themes import Themes


# todo: clean class up. Took from pyfa gauge, has a bunch of extra shit we don't need
Expand Down Expand Up @@ -50,7 +51,7 @@ def __init__(
self._old_percentage = 0
self._show_remaining = False

self.SetBackgroundColour(wx.Colour(51, 51, 51))
self.SetBackgroundColour(Themes.gaugeBackground())

self._tooltip = wx.ToolTip("0.00/100.00")
self.SetToolTip(self._tooltip)
Expand Down Expand Up @@ -169,10 +170,10 @@ def OnPaint(self, event):
dc = wx.AutoBufferedPaintDC(self)
rect = self.GetClientRect()

dc.SetBackground(wx.Brush(self.GetBackgroundColour()))
dc.SetBackground(wx.Brush(Themes.gaugeBackground()))
dc.Clear()

colour = self.GetBackgroundColour()
colour = Themes.gaugeBackground()

dc.SetBrush(wx.Brush(colour))
dc.SetPen(wx.Pen(colour))
Expand Down
7 changes: 6 additions & 1 deletion gui/auxWindow.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
# noinspection PyPackageRequirements
import wx

from gui.utils.themes import Themes
from gui.utils.dark import setDarkTitleBar


class AuxiliaryMixin:

Expand Down Expand Up @@ -52,7 +55,9 @@ def __init__(self, parent, id=None, title=None, pos=None, size=None, style=None,
self.Bind(wx.EVT_MENU, self.OnSuppressedAction, id=wx.ID_COPY)
self.Bind(wx.EVT_MENU, self.OnSuppressedAction, id=wx.ID_PASTE)
if 'wxMSW' in wx.PlatformInfo:
self.SetBackgroundColour(wx.SystemSettings.GetColour(wx.SYS_COLOUR_BTNFACE))
self.SetBackgroundColour(Themes.buttonFace())
self.SetForegroundColour(Themes.text())
setDarkTitleBar(self)

@classmethod
def openOne(cls, parent, *args, forceReopen=False, **kwargs):
Expand Down
4 changes: 2 additions & 2 deletions gui/builtinAdditionPanes/fighterView.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
from gui.builtinViewColumns.state import State
from gui.contextMenu import ContextMenu
from gui.fitCommands.helpers import getSimilarFighters
from gui.utils.themes import Themes
from gui.utils.staticHelpers import DragDropHelper
from service.fit import Fit
from service.market import Market
Expand Down Expand Up @@ -115,8 +116,7 @@ def fitChanged(self, event):
slot = getattr(FittingSlot, "F_{}".format(x.upper()))
used = fit.getSlotsUsed(slot)
total = fit.getNumSlots(slot)
color = wx.Colour(204, 51, 51) if used > total else wx.SystemSettings.GetColour(
wx.SYS_COLOUR_WINDOWTEXT)
color = wx.Colour(204, 51, 51) if used > total else Themes.text()

lbl = getattr(self, "label%sUsed" % x.capitalize())
lbl.SetLabel(str(int(used)))
Expand Down
4 changes: 3 additions & 1 deletion gui/builtinContextMenus/droneSplitStack.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import gui.fitCommands as cmd
import gui.mainFrame
from gui.contextMenu import ContextMenuSingle
from gui.utils.themes import ThemedDialog, Themes
from service.fit import Fit

_t = wx.GetTranslation
Expand Down Expand Up @@ -49,7 +50,7 @@ def activate(self, callingWindow, fullContext, mainItem, i):
DroneSplitStack.register()


class DroneStackSplit(wx.Dialog):
class DroneStackSplit(ThemedDialog):

def __init__(self, parent, value):
super().__init__(parent, title="Split Drone Stack", style=wx.DEFAULT_DIALOG_STYLE)
Expand All @@ -64,6 +65,7 @@ def __init__(self, parent, value):
bSizer1.Add(bSizer2, 0, wx.ALL, 10)

self.input = wx.TextCtrl(self, wx.ID_ANY, style=wx.TE_PROCESS_ENTER)
Themes.styleInput(self.input)
self.input.SetValue(str(value))

bSizer1.Add(self.input, 0, wx.LEFT | wx.RIGHT | wx.EXPAND, 15)
Expand Down
4 changes: 3 additions & 1 deletion gui/builtinContextMenus/fitPilotSecurity.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import gui.fitCommands as cmd
import gui.mainFrame
from gui.contextMenu import ContextMenuUnconditional
from gui.utils.themes import ThemedDialog, Themes
from service.fit import Fit

_t = wx.GetTranslation
Expand Down Expand Up @@ -101,7 +102,7 @@ def handleModeCustom(self, event):
FitPilotSecurityMenu.register()


class SecStatusChanger(wx.Dialog):
class SecStatusChanger(ThemedDialog):

def __init__(self, parent, value):
super().__init__(parent, title=_t('Change Security Status'), style=wx.DEFAULT_DIALOG_STYLE)
Expand All @@ -116,6 +117,7 @@ def __init__(self, parent, value):
bSizer1.Add(bSizer2, 0, wx.ALL, 10)

self.input = wx.TextCtrl(self, wx.ID_ANY, style=wx.TE_PROCESS_ENTER)
Themes.styleInput(self.input)
if value is None:
value = '0.0'
else:
Expand Down
4 changes: 3 additions & 1 deletion gui/builtinContextMenus/implantSetSave.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import gui.mainFrame
from gui.contextMenu import ContextMenuUnconditional
from gui.utils.themes import ThemedDialog, Themes
from service.fit import Fit

_t = wx.GetTranslation
Expand Down Expand Up @@ -39,7 +40,7 @@ def activate(self, callingWindow, fullContext, i):
ImplantSetSave.register()


class NameDialog(wx.Dialog):
class NameDialog(ThemedDialog):

def __init__(self, parent, value):
super().__init__(parent, title=_t('New Implant Set'), style=wx.DEFAULT_DIALOG_STYLE)
Expand All @@ -54,6 +55,7 @@ def __init__(self, parent, value):
bSizer1.Add(bSizer2, 0, wx.ALL, 10)

self.input = wx.TextCtrl(self, wx.ID_ANY, style=wx.TE_PROCESS_ENTER)
Themes.styleInput(self.input)
if value is None:
value = ''
else:
Expand Down
4 changes: 3 additions & 1 deletion gui/builtinContextMenus/itemAmountChange.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from eos.saveddata.fighter import Fighter as es_Fighter
from eos.saveddata.fit import Fit as es_Fit
from gui.contextMenu import ContextMenuCombined
from gui.utils.themes import ThemedDialog, Themes
from service.fit import Fit

# noinspection PyPackageRequirements
Expand Down Expand Up @@ -92,7 +93,7 @@ def activate(self, callingWindow, fullContext, mainItem, selection, i):
ChangeItemAmount.register()


class AmountChanger(wx.Dialog):
class AmountChanger(ThemedDialog):

def __init__(self, parent, value, limits=None):
super().__init__(parent, title=_t("Change Amount"), style=wx.DEFAULT_DIALOG_STYLE)
Expand All @@ -107,6 +108,7 @@ def __init__(self, parent, value, limits=None):
bSizer1.Add(bSizer2, 0, wx.ALL, 10)

self.input = wx.TextCtrl(self, wx.ID_ANY, style=wx.TE_PROCESS_ENTER)
Themes.styleInput(self.input)
self.input.SetValue(str(value))

bSizer1.Add(self.input, 0, wx.LEFT | wx.RIGHT | wx.EXPAND, 15)
Expand Down
4 changes: 3 additions & 1 deletion gui/builtinContextMenus/itemProjectionRange.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from eos.saveddata.module import Module as EosModule
from gui.contextMenu import ContextMenuCombined
from gui.fitCommands.helpers import getSimilarFighters, getSimilarModPositions
from gui.utils.themes import ThemedDialog, Themes
from service.fit import Fit

# noinspection PyPackageRequirements
Expand Down Expand Up @@ -72,7 +73,7 @@ def activate(self, callingWindow, fullContext, mainItem, selection, i):
ChangeItemProjectionRange.register()


class RangeChanger(wx.Dialog):
class RangeChanger(ThemedDialog):

def __init__(self, parent, value):
super().__init__(parent, title='Change Projection Range', style=wx.DEFAULT_DIALOG_STYLE)
Expand All @@ -87,6 +88,7 @@ def __init__(self, parent, value):
bSizer1.Add(bSizer2, 0, wx.ALL, 10)

self.input = wx.TextCtrl(self, wx.ID_ANY, style=wx.TE_PROCESS_ENTER)
Themes.styleInput(self.input)
if value is None:
value = ''
else:
Expand Down
Loading