1
0
mirror of https://github.com/EDCD/EDMarketConnector.git synced 2025-04-13 07:47:14 +03:00

themes: Use defined constants for which theme throughout

This has been relying on knowledge of the magic numbers for far too long.

As part of this, remove all the obfuscating "oh, default is 0, and we want
that or any other theme, so treat this like a boolean" nonsense.

Also, stop assuming that "> 1" is a synonym for "transparent theme".  Just
Do The Equality Check.
This commit is contained in:
Athanasius 2022-12-05 11:52:29 +00:00
parent 0f5f625cfd
commit 62e285b52e
No known key found for this signature in database
GPG Key ID: 772697E181BB2767
3 changed files with 87 additions and 45 deletions

View File

@ -1799,18 +1799,14 @@ class AppWindow(object):
def onenter(self, event=None) -> None:
"""Handle when our window gains focus."""
# TODO: This assumes that 1) transparent is at least 2, 2) there are
# no new themes added after that.
if config.get_int('theme') > 1:
if config.get_int('theme') == theme.THEME_TRANSPARENT:
self.w.attributes("-transparentcolor", '')
self.blank_menubar.grid_remove()
self.theme_menubar.grid(row=0, columnspan=2, sticky=tk.NSEW)
def onleave(self, event=None) -> None:
"""Handle when our window loses focus."""
# TODO: This assumes that 1) transparent is at least 2, 2) there are
# no new themes added after that.
if config.get_int('theme') > 1 and event.widget == self.w:
if config.get_int('theme') == theme.THEME_TRANSPARENT and event.widget == self.w:
self.w.attributes("-transparentcolor", 'grey4')
self.theme_menubar.grid_remove()
self.blank_menubar.grid(row=0, columnspan=2, sticky=tk.NSEW)
@ -1887,7 +1883,7 @@ sys.path: {sys.path}'''
)
if args.reset_ui:
config.set('theme', 0) # 'Default' theme uses ID 0
config.set('theme', theme.THEME_DEFAULT)
config.set('ui_transparency', 100) # 100 is completely opaque
config.delete('font', suppress=True)
config.delete('font_size', suppress=True)

View File

@ -308,6 +308,7 @@ class PreferencesDialog(tk.Toplevel):
button.bind("<Return>", lambda event: self.apply())
self.protocol("WM_DELETE_WINDOW", self._destroy)
# FIXME: Why are these being called when *creating* the Settings window?
# Selectively disable buttons depending on output settings
self.cmdrchanged()
self.themevarchanged()
@ -733,13 +734,14 @@ class PreferencesDialog(tk.Toplevel):
# Appearance theme and language setting
nb.Radiobutton(
# LANG: Label for 'Default' theme radio button
appearance_frame, text=_('Default'), variable=self.theme, value=0, command=self.themevarchanged
appearance_frame, text=_('Default'), variable=self.theme,
value=theme.THEME_DEFAULT, command=self.themevarchanged
).grid(columnspan=3, padx=self.BUTTONX, sticky=tk.W, row=row.get())
# Appearance theme setting
nb.Radiobutton(
# LANG: Label for 'Dark' theme radio button
appearance_frame, text=_('Dark'), variable=self.theme, value=1, command=self.themevarchanged
appearance_frame, text=_('Dark'), variable=self.theme, value=theme.THEME_DARK, command=self.themevarchanged
).grid(columnspan=3, padx=self.BUTTONX, sticky=tk.W, row=row.get())
if sys.platform == 'win32':
@ -748,7 +750,7 @@ class PreferencesDialog(tk.Toplevel):
# LANG: Label for 'Transparent' theme radio button
text=_('Transparent'), # Appearance theme setting
variable=self.theme,
value=2,
value=theme.THEME_TRANSPARENT,
command=self.themevarchanged
).grid(columnspan=3, padx=self.BUTTONX, sticky=tk.W, row=row.get())
@ -1149,7 +1151,12 @@ class PreferencesDialog(tk.Toplevel):
"""Update theme examples."""
self.theme_button_0['foreground'], self.theme_button_1['foreground'] = self.theme_colors
state = tk.NORMAL if self.theme.get() else tk.DISABLED
if self.theme.get() == theme.THEME_DEFAULT:
state = tk.DISABLED # type: ignore
else:
state = tk.NORMAL # type: ignore
self.theme_label_0['state'] = state
self.theme_label_1['state'] = state
self.theme_button_0['state'] = state

107
theme.py
View File

@ -259,24 +259,7 @@ class _Theme(object):
if not config.get_str('dark_highlight'):
config.set('dark_highlight', 'white')
if theme:
# Dark
(r, g, b) = root.winfo_rgb(config.get_str('dark_text'))
self.current = {
'background': 'grey4', # OSX inactive dark titlebar color
'foreground': config.get_str('dark_text'),
'activebackground': config.get_str('dark_text'),
'activeforeground': 'grey4',
'disabledforeground': f'#{int(r/384):02x}{int(g/384):02x}{int(b/384):02x}',
'highlight': config.get_str('dark_highlight'),
# Font only supports Latin 1 / Supplement / Extended, and a
# few General Punctuation and Mathematical Operators
# LANG: Label for commander name in main window
'font': (theme > 1 and not 0x250 < ord(_('Cmdr')[0]) < 0x3000 and
tk_font.Font(family='Euro Caps', size=10, weight=tk_font.NORMAL) or
'TkDefaultFont'),
}
else:
if theme == self.THEME_DEFAULT:
# (Mostly) system colors
style = ttk.Style()
self.current = {
@ -292,9 +275,30 @@ class _Theme(object):
'font': 'TkDefaultFont',
}
# Apply current theme to a widget and its children, and register it for future updates
else: # Dark *or* Transparent
(r, g, b) = root.winfo_rgb(config.get_str('dark_text'))
self.current = {
'background': 'grey4', # OSX inactive dark titlebar color
'foreground': config.get_str('dark_text'),
'activebackground': config.get_str('dark_text'),
'activeforeground': 'grey4',
'disabledforeground': f'#{int(r/384):02x}{int(g/384):02x}{int(b/384):02x}',
'highlight': config.get_str('dark_highlight'),
# Font only supports Latin 1 / Supplement / Extended, and a
# few General Punctuation and Mathematical Operators
# LANG: Label for commander name in main window
'font': (theme > 1 and not 0x250 < ord(_('Cmdr')[0]) < 0x3000 and
tk_font.Font(family='Euro Caps', size=10, weight=tk_font.NORMAL) or
'TkDefaultFont'),
}
def update(self, widget: tk.Widget) -> None:
"""
Apply current theme to a widget and its children.
Also, register it for future updates.
:param widget: Target widget.
"""
assert isinstance(widget, tk.Widget) or isinstance(widget, tk.BitmapImage), widget
if not self.current:
return # No need to call this for widgets created in plugin_app()
@ -375,8 +379,7 @@ class _Theme(object):
# Apply configured theme
def apply(self, root: tk.Tk) -> None: # noqa: CCR001
def apply(self, root: tk.Tk) -> None: # noqa: CCR001, C901
theme = config.get_int('theme')
self._colors(root, theme)
@ -392,25 +395,31 @@ class _Theme(object):
for widget in pair:
widget.grid_remove()
if isinstance(pair[0], tk.Menu):
if theme:
if theme == self.THEME_DEFAULT:
root['menu'] = pair[0]
else: # Dark *or* Transparent
root['menu'] = ''
pair[theme].grid(**gridopts)
else:
root['menu'] = pair[0]
else:
pair[theme].grid(**gridopts)
if self.active == theme:
return # Don't need to mess with the window manager
else:
self.active = theme
if sys.platform == 'darwin':
from AppKit import NSAppearance, NSApplication, NSMiniaturizableWindowMask, NSResizableWindowMask
root.update_idletasks() # need main window to be created
appearance = NSAppearance.appearanceNamed_(theme and
'NSAppearanceNameDarkAqua' or
'NSAppearanceNameAqua')
if theme == self.THEME_DEFAULT:
appearance = NSAppearance.appearanceNamed_('NSAppearanceNameAqua')
else: # Dark (Transparent only on win32)
appearance = NSAppearance.appearanceNamed_('NSAppearanceNameDarkAqua')
for window in NSApplication.sharedApplication().windows():
window.setStyleMask_(window.styleMask() & ~(
NSMiniaturizableWindowMask | NSResizableWindowMask)) # disable zoom
@ -426,14 +435,30 @@ class _Theme(object):
GetWindowLongW = ctypes.windll.user32.GetWindowLongW # noqa: N806 # ctypes
SetWindowLongW = ctypes.windll.user32.SetWindowLongW # noqa: N806 # ctypes
root.overrideredirect(theme and True or False)
root.attributes("-transparentcolor", theme > 1 and 'grey4' or '')
# FIXME: Lose the "treat this like a boolean" bullshit
if theme == self.THEME_DEFAULT:
root.overrideredirect(False)
else:
root.overrideredirect(True)
if theme == self.THEME_TRANSPARENT:
root.attributes("-transparentcolor", 'grey4')
else:
root.attributes("-transparentcolor", '')
root.withdraw()
root.update_idletasks() # Size and windows styles get recalculated here
hwnd = ctypes.windll.user32.GetParent(root.winfo_id())
SetWindowLongW(hwnd, GWL_STYLE, GetWindowLongW(hwnd, GWL_STYLE) & ~WS_MAXIMIZEBOX) # disable maximize
SetWindowLongW(hwnd, GWL_EXSTYLE, theme > 1 and WS_EX_APPWINDOW |
WS_EX_LAYERED or WS_EX_APPWINDOW) # Add to taskbar
if theme == self.THEME_TRANSPARENT:
SetWindowLongW(hwnd, GWL_EXSTYLE, WS_EX_APPWINDOW | WS_EX_LAYERED) # Add to taskbar
else:
SetWindowLongW(hwnd, GWL_EXSTYLE, WS_EX_APPWINDOW) # Add to taskbar
root.deiconify()
root.wait_visibility() # need main window to be displayed before returning
@ -446,11 +471,25 @@ class _Theme(object):
children = Window()
nchildren = c_uint()
XQueryTree(dpy, root.winfo_id(), byref(xroot), byref(parent), byref(children), byref(nchildren))
XChangeProperty(dpy, parent, motif_wm_hints_property, motif_wm_hints_property, 32,
PropModeReplace, theme and motif_wm_hints_dark or motif_wm_hints_normal, 5)
if theme == self.THEME_DEFAULT:
wm_hints = motif_wm_hints_normal
else: # Dark *or* Transparent
wm_hints = motif_wm_hints_dark
XChangeProperty(
dpy, parent, motif_wm_hints_property, motif_wm_hints_property, 32, PropModeReplace, wm_hints, 5
)
XFlush(dpy)
else:
root.overrideredirect(theme and 1 or 0)
if theme == self.THEME_DEFAULT:
root.overrideredirect(False)
else: # Dark *or* Transparent
root.overrideredirect(True)
root.deiconify()
root.wait_visibility() # need main window to be displayed before returning