HatchLing-TuneBox / themes.py
taellinglin's picture
Add Reitenland patriotic preset
f6df5f7 verified
Raw History Blame Contribute Delete
11.6 kB
"""HatchLing-TuneBox's patriotic themes: colours, background picture, banner and mottoes for the Preset dropdown.
The Preset dropdown picks the sheet preset (ling_tiles.PRESETS) and, here, the look of the whole app.
"""
import base64
import random
from functools import lru_cache
from pathlib import Path
ASSETS = Path(__file__).parent / 'assets'
NAME = 'HatchLing-TuneBox'
# (label, value): the values are the keys of ling_tiles.PRESETS, plus 'none'
LOOKS = [('none – ROYGBIV', 'none'),
('patriotic America', 'patriotic'),
('patriotic Korea – 대한민국', 'korea'),
('patriotic 灵 Ling Country – 天圆,地方', 'ling'),
('patriotic Reitenland', 'reitenland')]
INTRO = ('Pictures and Ling programs in, outline-and-crosshatch sheets, globes and music boxes out. '
'Everything is drawn in the seven Ling hues and hatched with torus, Möbius and tetrahedral line '
'families set by an ML-DSA-87 signature of the source.')
THEMES = {
'none': dict(
title='', mottoes=[], bg=None,
# ROYGBIV: one dark ground for page and panels, light text, the seven hues as accents
flat=True,
# LingStationX's palette: primary #005c80, accent #3baaeb, controls #3c3c3c, warning #ff5a40, text #cdd0d8, ground #1b1b1b
c=dict(primary='#005c80', primary_hover='#00709c', accent='#3baaeb', text='#cdd0d8', page='#1b1b1b', panel='#1b1b1b',
line='#3c3c3c', on_primary='#ffffff', field='#2a2a2a', field_text='#e6e8ee', chip='#3c3c3c', chip_hover='#4a4a4a',
scheme='dark', label='#2a2a2a')),
'patriotic': dict(
title='E Pluribus Unum',
mottoes=['E Pluribus Unum – out of many, one', 'We the People', 'Liberty and Justice for All', 'Putting People First',
'A Bridge to the 21st Century', 'Land of the Free, Home of the Brave'],
bg='bg_america.jpg', pos='center top', veil='rgba(10,49,97,.55)',
c=dict(primary='#b31942', primary_hover='#8f1434', accent='#0a3161', text='#0a1f3d', page='#0a3161',
panel='rgba(255,255,255,.90)', line='#9fb2cf', on_primary='#ffffff')),
'korea': dict(
title='대한민국 만세',
mottoes=['대한민국 만세! – Long live Korea!', '홍익인간 弘益人間 – Benefit broadly the human world',
'무궁화 삼천리 화려강산 – Mugunghwa, three thousand ri of splendid rivers and mountains',
'하나된 대한민국 – One Korea, together', '파이팅! – Fighting!', '다이나믹 코리아 – Dynamic Korea',
'광복 – Restoration of light'],
bg='bg_korea.jpg', pos='center center', veil='rgba(255,255,255,.35)',
c=dict(primary='#cd2e3a', primary_hover='#a82430', accent='#0047a0', text='#111111', page='#ffffff',
panel='rgba(255,255,255,.92)', line='#0047a0', on_primary='#ffffff')),
'ling': dict(
title='灵 天圆,地方 – Heaven is a Circle, Ground is a Square',
mottoes=['Heaven is a Circle, Ground is a Square – 天圆,地方', 'Balance · Harmony · Reciprocity',
'Mandate of Balance – nothing carried to excess', 'Mandate of Harmony – many hues, one sheet',
'Mandate of Reciprocity – what is drawn is given back',
'和 – Harmony, as in 和をもって貴しとなす', '天下為公 – All under heaven is for all', '为人民服务 – Serve the People',
'ชาติ ศาสนา พระมหากษัตริย์ – Nation, Religion, King', '홍익인간 – Benefit broadly all people'],
bg='bg_ling.jpg', pos='center center', veil='rgba(10,17,112,.62)',
c=dict(primary='#d4a006', primary_hover='#b58700', accent='#e62b2b', text='#0a1170', page='#0a1170',
panel='rgba(255,252,238,.92)', line='#d4a006', on_primary='#0a1170')),
# the flag's orange, red and white: three horizontal stripes
'reitenland': dict(
title='Reitenland', mottoes=['Orange, Red and White'],
bg='bg_reitenland.jpg', pos='center center', veil='rgba(255,255,255,.12)',
c=dict(primary='#cc0000', primary_hover='#a30000', accent='#ff8c00', text='#3a0d05', page='#cc0000',
panel='rgba(255,255,255,.93)', line='#ff8c00', on_primary='#ffffff')),
}
@lru_cache(maxsize=None)
def _data_uri(name: str) -> str:
return 'data:image/jpeg;base64,' + base64.b64encode((ASSETS / name).read_bytes()).decode()
def banner(look: str, rng=random) -> str:
"""Markdown for the top of the app: the name, then the theme's title and a motto."""
th = THEMES.get(look, THEMES['none'])
head = '# %s' % NAME + (' \n### %s' % th['title'] if th['title'] else '')
if th['mottoes']:
head += ' \n*%s*' % rng.choice(th['mottoes'])
return head + '\n\n' + INTRO
NEUTRALS = {'light': ('#f7f7fa', '#eceef4', '#dde0ea', '#c6cad8', '#8d93a8', '#5a6076', '#424860', '#2e3347', '#1d2133', '#111423'),
'dark': ('#14141f', '#1b1830', '#26233f', '#3a3658', '#6b678f', '#9a97b8', '#bcbad2', '#d6d5e6', '#e9e8f3', '#f4f4ff')}
def css(look: str) -> str:
"""A <style> element that dresses the whole page in a theme's colours and background picture."""
th = THEMES.get(look, THEMES['none']); c = {'field': '#ffffff', 'field_text': '#111111', 'chip': '#ffffff', 'chip_hover': '#eef0f6', 'scheme': 'light', **th['c']}; c.setdefault('label', c['line'])
v = {'--body-background-fill': c['page'], '--body-text-color': c['text'], '--block-title-text-color': c['text'],
'--block-label-text-color': c['text'], '--block-background-fill': c['panel'], '--background-fill-primary': c['panel'],
'--background-fill-secondary': c['panel'], '--border-color-primary': c['line'], '--block-border-color': c['line'],
'--input-background-fill': c['field'], '--color-accent': c['accent'], '--color-accent-soft': c['panel'],
'--link-text-color': c['accent'], '--link-text-color-hover': c['primary'],
'--button-primary-background-fill': c['primary'], '--button-primary-background-fill-hover': c['primary_hover'],
'--button-primary-text-color': c['on_primary'], '--button-primary-border-color': c['primary'],
'--slider-color': c['primary'], '--checkbox-background-color-selected': c['primary'],
'--checkbox-border-color-selected': c['primary'], '--button-secondary-text-color': c['text'],
'--body-text-color-subdued': c['text'], '--block-info-text-color': c['text'], '--block-label-background-fill': c['label'],
'--block-label-border-color': c['label'], '--checkbox-label-background-fill': c['chip'],
'--checkbox-label-background-fill-hover': c['chip_hover'], '--checkbox-label-background-fill-selected': c['chip'],
'--checkbox-label-text-color': c['field_text'], '--checkbox-label-text-color-selected': c['field_text'],
'--checkbox-label-border-color': c['line'], '--checkbox-background-color': c['field'], '--checkbox-border-color': c['line'],
'--button-secondary-background-fill': c['chip'], '--button-secondary-background-fill-hover': c['chip_hover'],
'--button-secondary-border-color': c['line'], '--input-text-color': c['field_text'],
'--input-placeholder-color': '#555555', '--panel-background-fill': c['panel'], '--table-even-background-fill': '#ffffff',
'--table-odd-background-fill': '#f4f5f9', '--table-text-color': '#111111', '--code-background-fill': '#f4f5f9',
**{'--neutral-%d' % n: col for n, col in zip((50, 100, 200, 300, 400, 500, 600, 700, 800, 900), NEUTRALS[c['scheme']])},
'color-scheme': c['scheme']}
out = '.gradio-container,.dark .gradio-container{%s}' % ';'.join('%s:%s' % kv for kv in v.items())
out += ('.gradio-container,.gradio-container label,.gradio-container .prose,.gradio-container .prose *,.gradio-container .info,'
'.gradio-container span,.gradio-container p{color:%s}'
'.gradio-container input,.gradio-container textarea,.gradio-container select,.gradio-container ul.options li{color:%s!important;background:%s}'
'html body .gradio-container.gradio-container [data-testid$="-group"] label,html body .gradio-container.gradio-container [data-testid$="-group"] label *:not(input){background:%s!important;'
'background-image:none!important;box-shadow:none!important;color:%s!important;opacity:1!important;filter:none!important}'
'.gradio-container button.primary,.gradio-container button.primary *{color:%s!important}'
'.gradio-container [data-testid="block-label"],.gradio-container [data-testid="block-label"] *{background:%s!important;color:%s!important}'
% (c['text'], c['field_text'], c['field'], c['chip'], c['field_text'], c['on_primary'], c['label'], c['field_text']))
if th.get('flat'):
out += '.gradio-container .form,.gradio-container .row,.gradio-container .gap,.gradio-container .form .block,.gradio-container .block .block{background:transparent!important}'
out += '.gradio-container .block,.gradio-container .form{border-color:rgba(255,255,255,.18)!important}'
out += '.hl-banner,.hl-banner>*{background:transparent!important;border:0!important;box-shadow:none!important;padding-left:0}'
out += '.tab-wrapper,.tab-container{background:transparent}.tab-container button{color:%s!important}' % c['text']
out += '.tab-container button.selected{border-color:#ff5a40!important;background:#005c80!important;border-radius:6px 6px 0 0}'
out += '.gradio-container{--checkbox-background-color-selected:#3baaeb;--checkbox-border-color-selected:#3baaeb;--slider-color:#3baaeb;--color-accent:#3baaeb}'
for n, col in enumerate(('#ff5a40', '#f5a623', '#f2d34a', '#4cd964', '#a070f0'), 1): # the menu bar's red, orange, yellow, green, violet
out += '.tab-container button:nth-child(%d){color:%s!important}' % (n, col)
out += '.tab-container button.selected{color:#ffffff!important}'
if th.get('grad'):
out += ('body,gradio-app{background:%s fixed!important}.gradio-container,.gradio-container .app,.gradio-container .main{background:transparent!important}'
'.hl-banner{background:%s;border:2px solid %s;border-radius:12px;padding:6px 18px}'
'.tab-wrapper,.tab-container{background:%s;border-radius:10px 10px 0 0}.tab-container button{color:%s!important}'
'.tab-container button.selected{border-color:%s!important;color:%s!important}'
% (th['grad'], c['panel'], c['primary'], c['panel'], c['text'], c['primary'], c['text']))
if th.get('bg'):
out += ('body,gradio-app{background-image:linear-gradient(%s,%s),url("%s")!important;background-size:cover!important;'
'background-position:%s!important;background-attachment:fixed!important;background-repeat:no-repeat!important}'
'.gradio-container,.gradio-container .app,.gradio-container .main,.gradio-container .wrap.default{background:transparent!important}'
'.hl-banner{background:%s;border:2px solid %s;border-radius:12px;padding:6px 18px}'
'.tab-wrapper,.tab-container{background:%s;border-radius:10px 10px 0 0}'
'.tab-container button{color:%s!important}'
'.tab-container button.selected{border-color:%s!important;color:%s!important}'
% (th['veil'], th['veil'], _data_uri(th['bg']), th['pos'], c['panel'], c['primary'], c['panel'], c['text'], c['primary'], c['text']))
return '<style>%s</style>' % out