234 lines
4.8 KiB
Python
234 lines
4.8 KiB
Python
|
|
#!/usr/bin/env python
|
||
|
|
import gi; gi.require_version('Gtk', '3.0')
|
||
|
|
from gi.repository import Gtk, Gdk
|
||
|
|
from functools import reduce
|
||
|
|
import sys, os, re
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
Colors = {
|
||
|
|
'AB' : { 'Name' : 'Active Back', 'Default' : '#579c8e' },
|
||
|
|
'AF' : { 'Name' : 'Active Fore', 'Default' : '#ffffff' },
|
||
|
|
'AL' : { 'Name' : 'Active Line', 'Default' : '#292929' },
|
||
|
|
'NB' : { 'Name' : 'Normal Back', 'Default' : '#383838' },
|
||
|
|
'NF' : { 'Name' : 'Normal Fore', 'Default' : '#dadada' },
|
||
|
|
'NL' : { 'Name' : 'Normal Line', 'Default' : '#292929' },
|
||
|
|
}
|
||
|
|
|
||
|
|
Options = {
|
||
|
|
'B?' : { 'Name' : 'Borders', 'Default' : True },
|
||
|
|
'H?' : { 'Name' : 'Active Handle', 'Default' : False },
|
||
|
|
'G?' : { 'Name' : 'Gradients', 'Default' : False },
|
||
|
|
'R?' : { 'Name' : 'Raised', 'Default' : False },
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
def Init (l):
|
||
|
|
for r in l.values():
|
||
|
|
r['Initial'] = r['Value'] = r['Default']
|
||
|
|
|
||
|
|
Init(Colors)
|
||
|
|
Init(Options)
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
Dir = os.path.dirname(os.path.realpath(sys.argv[0]))
|
||
|
|
InPath = Dir + '/themerc.in'
|
||
|
|
OutPath = Dir + '/themerc'
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
def InitV (k, vs, f, s):
|
||
|
|
if k in vs: vs[k]['Initial'] = vs[k]['Value'] = f(s)
|
||
|
|
|
||
|
|
with open(Dir + '/themerc') as f:
|
||
|
|
for l in f.readlines():
|
||
|
|
|
||
|
|
if l[0] != '#': continue
|
||
|
|
ss = l.strip().split(' ')
|
||
|
|
k, v = ss[0].lstrip('#'), ss[1]
|
||
|
|
|
||
|
|
InitV(k, Colors, lambda s: s, v)
|
||
|
|
InitV(k, Options, lambda s: (v == 'True'), v)
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
def Read (path):
|
||
|
|
with open(path) as f:
|
||
|
|
return f.read()
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
def Rgb8 (c):
|
||
|
|
return [int(c[i:i+2], 16) for i in (1, 3, 5)]
|
||
|
|
|
||
|
|
def Hex8FromRgb8 (c):
|
||
|
|
return '#%02x%02x%02x' % tuple(c)
|
||
|
|
|
||
|
|
def Hex8FromRgb (c):
|
||
|
|
return Hex8FromRgb8 (
|
||
|
|
map(lambda f: int(f * 0xFF), c)
|
||
|
|
)
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
def Subst (src, op, cl, fun):
|
||
|
|
|
||
|
|
s = src.split(op)
|
||
|
|
o = s[0]
|
||
|
|
|
||
|
|
for si in range(1, len(s)):
|
||
|
|
b = s[si].split(cl)
|
||
|
|
o = o + fun(b[0]) + b[1]
|
||
|
|
|
||
|
|
return o
|
||
|
|
|
||
|
|
|
||
|
|
def SubstCond (s):
|
||
|
|
|
||
|
|
kv = s.split(' ', 1)
|
||
|
|
yn = kv[1].split('!')
|
||
|
|
|
||
|
|
return yn[0] if Options[kv[0]]['Value'] else yn[1]
|
||
|
|
|
||
|
|
|
||
|
|
def SubstColor (s):
|
||
|
|
|
||
|
|
def pone (c):
|
||
|
|
if (c.startswith('#')): return Rgb8(c)
|
||
|
|
else: return Rgb8(Colors[c]['Value'])
|
||
|
|
|
||
|
|
def addc (a, b):
|
||
|
|
return map(lambda c0, c1: c0 + c1, a, b)
|
||
|
|
|
||
|
|
def divc (c, d):
|
||
|
|
return map(lambda c: int(c / d), c)
|
||
|
|
|
||
|
|
cs = [pone(c) for c in s.split(' ')];
|
||
|
|
return Hex8FromRgb8(divc(reduce(addc, cs), len(cs)))
|
||
|
|
|
||
|
|
|
||
|
|
def ExVals (vs):
|
||
|
|
return '\n'.join (
|
||
|
|
map (
|
||
|
|
lambda k: '#' + k + ' ' + str(vs[k]['Value']), vs
|
||
|
|
)
|
||
|
|
) + '\n'
|
||
|
|
|
||
|
|
|
||
|
|
def Apply ():
|
||
|
|
|
||
|
|
s = Read(InPath)
|
||
|
|
|
||
|
|
s = Subst(s, '[', ']', SubstCond)
|
||
|
|
s = Subst(s, '{', '}', SubstColor)
|
||
|
|
|
||
|
|
s = ExVals(Colors) + ExVals(Options) + '\n' + s
|
||
|
|
|
||
|
|
with open(OutPath, 'w') as of: of.write(s)
|
||
|
|
os.system('openbox --reconfigure')
|
||
|
|
|
||
|
|
|
||
|
|
def Reveal ():
|
||
|
|
for c in Colors.values():
|
||
|
|
c['Button'].set_color(Gdk.color_parse(c['Value']))
|
||
|
|
for o in Options.values():
|
||
|
|
o['Switch'].set_state(o['Value'])
|
||
|
|
|
||
|
|
|
||
|
|
def Reset (key):
|
||
|
|
for c in list(Colors.values()) + list(Options.values()):
|
||
|
|
c['Value'] = c[key]
|
||
|
|
Reveal()
|
||
|
|
|
||
|
|
|
||
|
|
def FromGtk ():
|
||
|
|
|
||
|
|
m = Gtk.Menu()
|
||
|
|
i = Gtk.MenuItem()
|
||
|
|
w = Gtk.Window()
|
||
|
|
m.add(i)
|
||
|
|
|
||
|
|
ms = m.get_style_context()
|
||
|
|
rs = i.get_style_context()
|
||
|
|
ws = w.get_style_context()
|
||
|
|
|
||
|
|
def ccc (key, gc):
|
||
|
|
Colors[key]['Value'] = Hex8FromRgb([gc.red, gc.green, gc.blue])
|
||
|
|
|
||
|
|
ccc('AB', rs.get_background_color(Gtk.StateFlags.PRELIGHT))
|
||
|
|
ccc('AF', rs.get_color(Gtk.StateFlags.PRELIGHT))
|
||
|
|
ccc('AL', ms.get_border_color(Gtk.StateFlags.PRELIGHT))
|
||
|
|
ccc('NB', ws.get_background_color(Gtk.StateFlags.NORMAL))
|
||
|
|
ccc('NF', ws.get_color(Gtk.StateFlags.NORMAL))
|
||
|
|
ccc('NL', ms.get_border_color(Gtk.StateFlags.NORMAL))
|
||
|
|
|
||
|
|
Reveal()
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
W = Gtk.Window(title = "Lean OB")
|
||
|
|
W.set_icon_name("applications-graphics")
|
||
|
|
W.connect("destroy", lambda e: Gtk.main_quit())
|
||
|
|
W.set_resizable(False)
|
||
|
|
W.set_border_width(8)
|
||
|
|
|
||
|
|
T = Gtk.Grid()
|
||
|
|
T.set_row_spacing(4)
|
||
|
|
T.set_column_spacing(4)
|
||
|
|
T.Rows = 0
|
||
|
|
|
||
|
|
def AddRow (t, label, o):
|
||
|
|
t.attach(Gtk.Label(label + ':'), 0, t.Rows, 1, 1)
|
||
|
|
t.attach(o, 1, T.Rows, 1, 1)
|
||
|
|
t.Rows = t.Rows + 1
|
||
|
|
|
||
|
|
def SetC (ck, c):
|
||
|
|
Colors[ck]['Value'] = Hex8FromRgb(c.to_floats())
|
||
|
|
|
||
|
|
def SetO (ok, o):
|
||
|
|
Options[ok]['Value'] = o
|
||
|
|
|
||
|
|
for ck in sorted(Colors):
|
||
|
|
c = Colors[ck]
|
||
|
|
cbtn = c['Button'] = Gtk.ColorButton(color = Gdk.color_parse(c['Value']))
|
||
|
|
cbtn.connect('color-set', lambda b, k: SetC(k, b.get_color()), ck)
|
||
|
|
AddRow(T, c['Name'], cbtn)
|
||
|
|
|
||
|
|
for ok in sorted(Options):
|
||
|
|
o = Options[ok]
|
||
|
|
osw = o['Switch'] = Gtk.Switch(state = o['Value'])
|
||
|
|
osw.connect('state-set', lambda s, v, k: SetO(k, v), ok)
|
||
|
|
AddRow(T, o['Name'], osw)
|
||
|
|
|
||
|
|
DefaultBtn = Gtk.Button("Default")
|
||
|
|
RevertBtn = Gtk.Button("Revert")
|
||
|
|
FromGtkBtn = Gtk.Button("From GTK")
|
||
|
|
ApplyBtn = Gtk.Button("Apply")
|
||
|
|
|
||
|
|
DefaultBtn.connect('clicked', lambda e: Reset('Default'))
|
||
|
|
RevertBtn.connect('clicked', lambda e: Reset('Initial'))
|
||
|
|
FromGtkBtn.connect('clicked', lambda e: FromGtk())
|
||
|
|
ApplyBtn.connect('clicked', lambda e: Apply())
|
||
|
|
|
||
|
|
V = Gtk.VBox(spacing = 8)
|
||
|
|
V.pack_start(DefaultBtn, True, True, 0)
|
||
|
|
V.pack_start(FromGtkBtn, True, True, 0)
|
||
|
|
V.pack_start(T, True, True, 0)
|
||
|
|
V.pack_start(RevertBtn, True, True, 0)
|
||
|
|
V.pack_start(ApplyBtn, True, True, 0)
|
||
|
|
W.add(V)
|
||
|
|
|
||
|
|
W.show_all()
|
||
|
|
Gtk.main()
|