calibre/src/pyj/book_list/theme.pyj

146 lines
4.2 KiB
Plaintext

# vim:fileencoding=utf-8
# License: GPL v3 Copyright: 2015, Kovid Goyal <kovid at kovidgoyal.net>
from __python__ import hash_literals, bound_methods
DARK = '#39322B'
LIGHT = '#F6F3E9'
LIGHT_DARKER = '#b6b3a8'
LIGHT_GRADIENT = 'linear-gradient(to bottom, {}, {})'.format(LIGHT, LIGHT_DARKER)
DT_DARK = '#2d2d2d'
DT_DARK_DARKER = 'black'
DT_DARK_LIGHTER = '#777'
DT_DARK_LIGTHER_CONTRAST = '#1d1d1d'
DT_LIGHT = '#ddd'
DARK_GRADIENT = 'linear-gradient(to bottom, {}, {})'.format(DT_DARK_LIGHTER, DT_DARK)
def c(light, dark):
return {'light': light, 'dark': dark or light}
DEFAULT_COLORS = {
# General colors
'window-background': c(LIGHT, DT_DARK),
'window-background2': c(LIGHT_DARKER, DT_DARK_LIGHTER),
'window-foreground': c(DARK, DT_LIGHT),
'window-error-foreground': c('red', '#C40233'),
'window-hover-foreground': c('red', '#C40233'),
'link-foreground': c('blue', '#6cb4ee'),
# Top bar specific colors
'bar-background': c(DARK, DT_DARK_LIGHTER),
'bar-foreground': c(LIGHT, DT_DARK_LIGTHER_CONTRAST),
'bar-highlight': c('yellow'),
'heart': c('#B92111'),
# Item list colors
'list-hover-background': c(DARK, DT_DARK_LIGHTER),
'list-hover-foreground': c(LIGHT, DT_DARK_LIGTHER_CONTRAST),
# Tree colors
'tree-highlight-item': c(LIGHT_DARKER, DT_DARK_LIGHTER),
# Button colors
'button-start': c(DARK, DT_LIGHT),
'button-end': c('#49423B', '#666'),
'button-text': c(LIGHT, DT_DARK),
# Dialog colors
'dialog-background': c(LIGHT, DT_DARK),
'dialog-background-image': c(LIGHT_GRADIENT, DARK_GRADIENT),
'dialog-foreground': c(DARK, DT_LIGHT),
# Native controls
'input-background': c('field', DT_DARK_DARKER),
'input-foreground': c('fieldtext', DT_LIGHT),
'input-focus-outline-color': c('#4D90FE', DT_LIGHT),
}
DEFAULT_SIZES = {
'title': '1.4rem',
'item-list-title': '1.1rem',
'item-list-subtitle': '0.8rem',
}
DEFAULT_FONTS = {
'main': 'sans-serif'
}
def set_ui_colors(is_dark_theme):
attr = 'dark' if is_dark_theme else 'light'
s = document.documentElement.style
for k in DEFAULT_COLORS:
val = DEFAULT_COLORS[k][attr]
s.setProperty('--calibre-color-' + k, val)
get_color_as_rgba.cache = {}
cached_color_to_rgba.cache = {}
document.documentElement.style.colorScheme = 'dark' if is_dark_theme else 'light'
def browser_in_dark_mode():
return window.matchMedia('(prefers-color-scheme: dark)').matches
def color_scheme():
return 'dark' if browser_in_dark_mode() or document.documentElement.style.colorScheme is 'dark' else 'light'
def css_for_variables():
input_css = '''
input, textarea {
color: var(--calibre-color-input-foreground); \
background-color: var(--calibre-color-input-background); \
}
input:focus, textarea:focus {
outline-color: var(--calibre-color-input-focus-outline-color); \
}
'''
is_dark_theme = browser_in_dark_mode()
attr = 'dark' if is_dark_theme else 'light'
ans = v'[]'
for k in DEFAULT_COLORS:
val = DEFAULT_COLORS[k][attr]
ans.push(f'--calibre-color-{k}: {val};')
return f':root {{ color-scheme: {attr}; ' + ans.join('\n') + '}\n\n' + input_css
def get_color(name):
return f'var(--calibre-color-{name})'
def color_to_rgba(color):
# take an arbitrary color spec and return it as [r, g, b, a]
cvs = document.createElement('canvas')
cvs.height = 1
cvs.width = 1
if color.startsWith('var('):
color = window.getComputedStyle(document.documentElement).getPropertyValue(color[4:-1])
ctx = cvs.getContext('2d')
ctx.fillStyle = color
ctx.fillRect(0, 0, 1, 1)
return ctx.getImageData(0, 0, 1, 1).data
def cached_color_to_rgba(color):
cache = cached_color_to_rgba.cache
if not cache[color]:
cache[color] = color_to_rgba(color)
return cache[color]
cached_color_to_rgba.cache = {}
def get_color_as_rgba(name):
cache = get_color_as_rgba.cache
if not cache[name]:
cache[name] = color_to_rgba(get_color(name))
return cache[name]
get_color_as_rgba.cache = {}
def get_font_size(name):
return DEFAULT_SIZES[name]
def get_font_family(name):
name = name or 'main'
return DEFAULT_FONTS[name]