[themes] Make it possible to merge themes to get "icon themes"

Add code that allows themes to be merged (i.e. if certain elements are
not present in a theme, another theme can be "overlaid" to add missing
elements).

Effectively, this is used to create the logical concept of an "icon
theme", which is loaded after the main theme. So, the main theme can
define colors, and the icon theme fills in any missing elements
(practically, all the icons in the form of prefixes and suffixes).

Icon sets are defined in a theme using the "icons" directive, which
should be an array.

see #17
This commit is contained in:
Tobi-wan Kenobi 2016-11-25 21:06:24 +01:00
parent f6db8b0a85
commit 209fa83324
10 changed files with 296 additions and 600 deletions

View file

@ -52,7 +52,7 @@ class Output(bumblebee.output.Output):
}) })
self._data.append({ self._data.append({
u"full_text": "{}{}{}".format( u"full_text": " {} {} {} ".format(
theme.prefix(widget), theme.prefix(widget),
widget.text(), widget.text(),
theme.suffix(widget) theme.suffix(widget)

View file

@ -1,4 +1,5 @@
import os import os
import copy
import json import json
import yaml import yaml
import glob import glob
@ -14,16 +15,44 @@ class Theme:
def __init__(self, config): def __init__(self, config):
self._config = config self._config = config
if os.path.isfile("{}/{}.yaml".format(getpath(), config.theme())): self._data = self.get_theme(config.theme())
with open("{}/{}.yaml".format(getpath(), config.theme())) as f:
self._data = yaml.load(f) for iconset in self._data.get("icons", []):
else: self.merge(self._data, self.get_theme(iconset))
with open("{}/{}.json".format(getpath(), config.theme())) as f:
self._data = json.load(f)
self._defaults = self._data.get("defaults", {}) self._defaults = self._data.get("defaults", {})
self._cycles = self._defaults.get("cycle", []) self._cycles = self._defaults.get("cycle", [])
self.begin() self.begin()
def get_theme(self, name):
for path in [ getpath(), "{}/icons/".format(getpath()) ]:
if os.path.isfile("{}/{}.yaml".format(path, name)):
with open("{}/{}.yaml".format(path, name)) as f:
return yaml.load(f)
if os.path.isfile("{}/{}.json".format(path, name)):
with open("{}/{}.json".format(path, name)) as f:
return json.load(f)
return None
# algorithm copied from
# http://blog.impressiver.com/post/31434674390/deep-merge-multiple-python-dicts
# nicely done :)
def merge(self, target, *args):
if len(args) > 1:
for item in args:
self.merge(item)
return target
item = args[0]
if not isinstance(item, dict):
return item
for key, value in item.iteritems():
if key in target and isinstance(target[key], dict):
self.merge(target[key], value)
else:
target[key] = copy.deepcopy(value)
return target
def begin(self): def begin(self):
self._config.set("theme.cycleidx", 0) self._config.set("theme.cycleidx", 0)
self._cycle = self._cycles[0] if len(self._cycles) > 0 else {} self._cycle = self._cycles[0] if len(self._cycles) > 0 else {}

View file

@ -1,128 +1,7 @@
{ {
"icons": [ "ascii" ],
"defaults": { "defaults": {
"prefix": " ",
"suffix" : " ",
"urgent": true, "urgent": true,
"fg": "#aabbcc" "fg": "#aabbcc"
},
"date": {
"prefix": " "
},
"time": {
"prefix": " "
},
"memory": {
"prefix": " ram "
},
"cpu": {
"prefix": " cpu "
},
"disk": {
"prefix": " hdd "
},
"dnf": {
"prefix": " dnf "
},
"brightness": {
"prefix": " o "
},
"cmus": {
"states": {
"playing": {
"prefix": " > "
},
"paused": {
"prefix": " || "
},
"stopped": {
"prefix": " [] "
}
},
"prev": {
"prefix": " |< "
},
"next": {
"prefix": " >| "
},
"shuffle": {
"states": { "on": { "prefix": " S " }, "off": { "prefix": " [s] " } }
},
"repeat": {
"states": { "on": { "prefix": " R " }, "off": { "prefix": " [r] " } }
}
},
"pasink": {
"states": {
"muted": {
"prefix": " audio(mute) "
},
"unmuted": {
"prefix": " audio "
}
}
},
"pasource": {
"states": {
"muted": {
"prefix": " mic(mute) "
},
"unmuted": {
"prefix": " mic "
}
}
},
"nic": {
"states": {
"wireless-up": {
"prefix": " wifi "
},
"wireless-down": {
"prefix": " wifi "
},
"wired-up": {
"prefix": " lan "
},
"wired-down": {
"prefix": " lan "
},
"tunnel-up": {
"prefix": " tun "
},
"tunnel-down": {
"prefix": " tun "
}
}
},
"battery": {
"states": {
"charged": {
"suffix": " full "
},
"charging": {
"suffix": " chr "
},
"AC": {
"suffix": " ac "
},
"discharging-10": {
"prefix": " ! ",
"suffix": " dis "
},
"discharging-25": {
"suffix": " dis "
},
"discharging-50": {
"suffix": " dis "
},
"discharging-80": {
"suffix": " dis "
},
"discharging-100": {
"suffix": " dis "
}
}
},
"caffeine": {
"states": { "activated": {"prefix": "   " }, "deactivated": { "prefix": "   " } }
} }
} }

View file

@ -1,4 +1,5 @@
{ {
"icons": [ "paxy97", "awesome-fonts" ],
"defaults": { "defaults": {
"prefix": " ", "prefix": " ",
"suffix" : " ", "suffix" : " ",
@ -18,26 +19,9 @@
"bg-warning": "#d79921", "bg-warning": "#d79921",
"default-separators": false, "default-separators": false,
"separator-block-width": 0, "separator-block-width": 0
"separator": ""
},
"date": {
"prefix": "  "
},
"time": {
"prefix": "  "
},
"memory": {
"prefix": "  "
},
"cpu": {
"prefix": "  "
},
"disk": {
"prefix": "  "
}, },
"dnf": { "dnf": {
"prefix": "  ",
"states": { "states": {
"good": { "good": {
"fg": "#002b36", "fg": "#002b36",
@ -45,116 +29,16 @@
} }
} }
}, },
"pasink": {
"states": {
"muted": {
"prefix": "  "
},
"unmuted": {
"prefix": "  "
}
}
},
"pasource": {
"states": {
"muted": {
"prefix": "  "
},
"unmuted": {
"prefix": "  "
}
}
},
"nic": {
"states": {
"wireless-up": {
"prefix": "  "
},
"wireless-down": {
"prefix": "  "
},
"wired-up": {
"prefix": "  "
},
"wired-down": {
"prefix": "  "
},
"tunnel-up": {
"prefix": "  "
},
"tunnel-down": {
"prefix": "  "
}
}
},
"battery": { "battery": {
"states": { "states": {
"charged": { "charged": {
"prefix": "  ",
"suffix": "  ",
"fg": "#1d2021", "fg": "#1d2021",
"bg": "#b8bb26" "bg": "#b8bb26"
}, },
"AC": { "AC": {
"suffix": "  ",
"fg": "#1d2021", "fg": "#1d2021",
"bg": "#b8bb26" "bg": "#b8bb26"
},
"charging": {
"prefix": [ "  ", "  ", "  ", "  ", "  " ],
"suffix": "  "
},
"discharging-10": {
"prefix": "  ",
"suffix": "  "
},
"discharging-25": {
"prefix": "  ",
"suffix": "  "
},
"discharging-50": {
"prefix": "  ",
"suffix": "  "
},
"discharging-80": {
"prefix": "  ",
"suffix": "  "
},
"discharging-100": {
"prefix": "  ",
"suffix": "  "
} }
} }
},
"cmus": {
"states": {
"playing": {
"prefix": "  "
},
"paused": {
"prefix": "  "
},
"stopped": {
"prefix": "  "
}
},
"prev": {
"prefix": "  "
},
"next": {
"prefix": "  "
},
"shuffle": {
"states": { "on": { "prefix": "  " }, "off": { "prefix": "  " } }
},
"repeat": {
"states": { "on": { "prefix": "  " }, "off": { "prefix": "  " } }
}
},
"brightness": {
"prefix": "  "
},
"caffeine": {
"states": { "activated": {"prefix": "   " }, "deactivated": { "prefix": "   " } }
} }
} }

116
themes/icons/ascii.json Normal file
View file

@ -0,0 +1,116 @@
{
"memory": {
"prefix": "ram"
},
"cpu": {
"prefix": "cpu"
},
"disk": {
"prefix": "hdd"
},
"dnf": {
"prefix": "dnf"
},
"brightness": {
"prefix": "o"
},
"cmus": {
"states": {
"playing": {
"prefix": ">"
},
"paused": {
"prefix": "||"
},
"stopped": {
"prefix": "[]"
}
},
"prev": {
"prefix": "|<"
},
"next": {
"prefix": ">|"
},
"shuffle": {
"states": { "on": { "prefix": "S" }, "off": { "prefix": "[s]" } }
},
"repeat": {
"states": { "on": { "prefix": "R" }, "off": { "prefix": "[r]" } }
}
},
"pasink": {
"states": {
"muted": {
"prefix": "audio(mute)"
},
"unmuted": {
"prefix": "audio"
}
}
},
"pasource": {
"states": {
"muted": {
"prefix": "mic(mute)"
},
"unmuted": {
"prefix": "mic"
}
}
},
"nic": {
"states": {
"wireless-up": {
"prefix": "wifi"
},
"wireless-down": {
"prefix": "wifi"
},
"wired-up": {
"prefix": "lan"
},
"wired-down": {
"prefix": "lan"
},
"tunnel-up": {
"prefix": "tun"
},
"tunnel-down": {
"prefix": "tun"
}
}
},
"battery": {
"states": {
"charged": {
"suffix": "full"
},
"charging": {
"suffix": "chr"
},
"AC": {
"suffix": "ac"
},
"discharging-10": {
"prefix": "!",
"suffix": "dis"
},
"discharging-25": {
"suffix": "dis"
},
"discharging-50": {
"suffix": "dis"
},
"discharging-80": {
"suffix": "dis"
},
"discharging-100": {
"suffix": "dis"
}
}
},
"caffeine": {
"states": { "activated": {"prefix": "caf-on" }, "deactivated": { "prefix": "caf-off " } }
}
}

View file

@ -0,0 +1,131 @@
{
"defaults": {
"separator": ""
},
"date": {
"prefix": ""
},
"time": {
"prefix": ""
},
"memory": {
"prefix": ""
},
"cpu": {
"prefix": ""
},
"disk": {
"prefix": ""
},
"dnf": {
"prefix": ""
},
"brightness": {
"prefix": ""
},
"cmus": {
"states": {
"playing": {
"prefix": ""
},
"paused": {
"prefix": ""
},
"stopped": {
"prefix": ""
}
},
"prev": {
"prefix": ""
},
"next": {
"prefix": ""
},
"shuffle": {
"states": { "on": { "prefix": "" }, "off": { "prefix": "" } }
},
"repeat": {
"states": { "on": { "prefix": "" }, "off": { "prefix": "" } }
}
},
"pasink": {
"states": {
"muted": {
"prefix": ""
},
"unmuted": {
"prefix": ""
}
}
},
"pasource": {
"states": {
"muted": {
"prefix": ""
},
"unmuted": {
"prefix": ""
}
}
},
"nic": {
"states": {
"wireless-up": {
"prefix": ""
},
"wireless-down": {
"prefix": ""
},
"wired-up": {
"prefix": ""
},
"wired-down": {
"prefix": ""
},
"tunnel-up": {
"prefix": ""
},
"tunnel-down": {
"prefix": ""
}
}
},
"battery": {
"states": {
"charged": {
"prefix": "",
"suffix": ""
},
"AC": {
"suffix": ""
},
"charging": {
"prefix": [ "", "", "", "", "" ],
"suffix": ""
},
"discharging-10": {
"prefix": "",
"suffix": ""
},
"discharging-25": {
"prefix": "",
"suffix": ""
},
"discharging-50": {
"prefix": "",
"suffix": ""
},
"discharging-80": {
"prefix": "",
"suffix": ""
},
"discharging-100": {
"prefix": "",
"suffix": ""
}
}
},
"caffeine": {
"states": { "activated": {"prefix": " " }, "deactivated": { "prefix": " " } }
}
}

5
themes/icons/paxy97.json Normal file
View file

@ -0,0 +1,5 @@
{
"memory": {
"prefix": "  "
}
}

View file

@ -1,7 +1,6 @@
{ {
"icons": [ "awesome-fonts" ],
"defaults": { "defaults": {
"prefix": " ",
"suffix" : " ",
"cycle": [ "cycle": [
{ {
"fg": "#ffd700", "fg": "#ffd700",
@ -17,26 +16,9 @@
"fg-warning": "#d75f00", "fg-warning": "#d75f00",
"bg-warning": "#ffd700", "bg-warning": "#ffd700",
"default_separators": false, "default_separators": false
"separator": ""
},
"date": {
"prefix": "  "
},
"time": {
"prefix": "  "
},
"memory": {
"prefix": "  "
},
"cpu": {
"prefix": "  "
},
"disk": {
"prefix": "  "
}, },
"dnf": { "dnf": {
"prefix": "  ",
"states": { "states": {
"good": { "good": {
"fg": "#494949", "fg": "#494949",
@ -44,116 +26,16 @@
} }
} }
}, },
"brightness": {
"prefix": "  "
},
"cmus": {
"states": {
"playing": {
"prefix": "  "
},
"paused": {
"prefix": "  "
},
"stopped": {
"prefix": "  "
}
},
"prev": {
"prefix": "  "
},
"next": {
"prefix": "  "
},
"shuffle": {
"states": { "on": { "prefix": "  " }, "off": { "prefix": "  " } }
},
"repeat": {
"states": { "on": { "prefix": "  " }, "off": { "prefix": "  " } }
}
},
"pasink": {
"states": {
"muted": {
"prefix": "  "
},
"unmuted": {
"prefix": "  "
}
}
},
"pasource": {
"states": {
"muted": {
"prefix": "  "
},
"unmuted": {
"prefix": "  "
}
}
},
"nic": {
"states": {
"wireless-up": {
"prefix": "  "
},
"wireless-down": {
"prefix": "  "
},
"wired-up": {
"prefix": "  "
},
"wired-down": {
"prefix": "  "
},
"tunnel-up": {
"prefix": "  "
},
"tunnel-down": {
"prefix": "  "
}
}
},
"battery": { "battery": {
"states": { "states": {
"charged": { "charged": {
"prefix": "  ",
"suffix": "  ",
"fg": "#494949", "fg": "#494949",
"bg": "#41db00" "bg": "#41db00"
}, },
"AC": { "AC": {
"suffix": "  ",
"fg": "#494949", "fg": "#494949",
"bg": "#41db00" "bg": "#41db00"
},
"charging": {
"prefix": [ "  ", "  ", "  ", "  ", "  " ],
"suffix": "  "
},
"discharging-10": {
"prefix": "  ",
"suffix": "  "
},
"discharging-25": {
"prefix": "  ",
"suffix": "  "
},
"discharging-50": {
"prefix": "  ",
"suffix": "  "
},
"discharging-80": {
"prefix": "  ",
"suffix": "  "
},
"discharging-100": {
"prefix": "  ",
"suffix": "  "
} }
} }
},
"caffeine": {
"states": { "activated": {"prefix": "   " }, "deactivated": { "prefix": "   " } }
} }
} }

View file

@ -1,7 +1,6 @@
{ {
"icons": [ "awesome-fonts" ],
"defaults": { "defaults": {
"prefix": " ",
"suffix" : " ",
"cycle": [ "cycle": [
{ {
"fg": "#93a1a1", "fg": "#93a1a1",
@ -18,26 +17,9 @@
"bg-warning": "#b58900", "bg-warning": "#b58900",
"default-separators": false, "default-separators": false,
"separator-block-width": 0, "separator-block-width": 0
"separator": ""
},
"date": {
"prefix": "  "
},
"time": {
"prefix": "  "
},
"memory": {
"prefix": "  "
},
"cpu": {
"prefix": "  "
},
"disk": {
"prefix": "  "
}, },
"dnf": { "dnf": {
"prefix": "  ",
"states": { "states": {
"good": { "good": {
"fg": "#002b36", "fg": "#002b36",
@ -45,116 +27,16 @@
} }
} }
}, },
"brightness": {
"prefix": "  "
},
"cmus": {
"states": {
"playing": {
"prefix": "  "
},
"paused": {
"prefix": "  "
},
"stopped": {
"prefix": "  "
}
},
"prev": {
"prefix": "  "
},
"next": {
"prefix": "  "
},
"shuffle": {
"states": { "on": { "prefix": "  " }, "off": { "prefix": "  " } }
},
"repeat": {
"states": { "on": { "prefix": "  " }, "off": { "prefix": "  " } }
}
},
"pasink": {
"states": {
"muted": {
"prefix": "  "
},
"unmuted": {
"prefix": "  "
}
}
},
"pasource": {
"states": {
"muted": {
"prefix": "  "
},
"unmuted": {
"prefix": "  "
}
}
},
"nic": {
"states": {
"wireless-up": {
"prefix": "  "
},
"wireless-down": {
"prefix": "  "
},
"wired-up": {
"prefix": "  "
},
"wired-down": {
"prefix": "  "
},
"tunnel-up": {
"prefix": "  "
},
"tunnel-down": {
"prefix": "  "
}
}
},
"battery": { "battery": {
"states": { "states": {
"charged": { "charged": {
"prefix": "  ",
"suffix": "  ",
"fg": "#002b36", "fg": "#002b36",
"bg": "#859900" "bg": "#859900"
}, },
"AC": { "AC": {
"suffix": "  ",
"fg": "#002b36", "fg": "#002b36",
"bg": "#859900" "bg": "#859900"
},
"charging": {
"prefix": [ "  ", "  ", "  ", "  ", "  " ],
"suffix": "  "
},
"discharging-10": {
"prefix": "  ",
"suffix": "  "
},
"discharging-25": {
"prefix": "  ",
"suffix": "  "
},
"discharging-50": {
"prefix": "  ",
"suffix": "  "
},
"discharging-80": {
"prefix": "  ",
"suffix": "  "
},
"discharging-100": {
"prefix": "  ",
"suffix": "  "
} }
} }
},
"caffeine": {
"states": { "activated": {"prefix": "   " }, "deactivated": { "prefix": "   " } }
} }
} }

View file

@ -1,7 +1,6 @@
{ {
"icons": [ "ascii" ],
"defaults": { "defaults": {
"prefix": " ",
"suffix" : " ",
"cycle": [ "cycle": [
{ {
"fg": "#93a1a1", "fg": "#93a1a1",
@ -20,23 +19,7 @@
"default_separators": false, "default_separators": false,
"separator": "|" "separator": "|"
}, },
"date": {
"prefix": " "
},
"time": {
"prefix": " "
},
"memory": {
"prefix": " ram "
},
"cpu": {
"prefix": " cpu "
},
"disk": {
"prefix": " hdd "
},
"dnf": { "dnf": {
"prefix": " dnf ",
"states": { "states": {
"good": { "good": {
"fg": "#002b36", "fg": "#002b36",
@ -44,110 +27,15 @@
} }
} }
}, },
"brightness": {
"prefix": " o "
},
"cmus": {
"states": {
"playing": {
"prefix": " > "
},
"paused": {
"prefix": " || "
},
"stopped": {
"prefix": " [] "
}
},
"prev": {
"prefix": " |< "
},
"next": {
"prefix": " >| "
},
"shuffle": {
"states": { "on": { "prefix": " S " }, "off": { "prefix": " [s] " } }
},
"repeat": {
"states": { "on": { "prefix": " R " }, "off": { "prefix": " [r] " } }
}
},
"pasink": {
"states": {
"muted": {
"prefix": " audio(mute) "
},
"unmuted": {
"prefix": " audio "
}
}
},
"pasource": {
"states": {
"muted": {
"prefix": " mic(mute) "
},
"unmuted": {
"prefix": " mic "
}
}
},
"nic": {
"states": {
"wireless-up": {
"prefix": " wifi "
},
"wireless-down": {
"prefix": " wifi "
},
"wired-up": {
"prefix": " lan "
},
"wired-down": {
"prefix": " lan "
},
"tunnel-up": {
"prefix": " tun "
},
"tunnel-down": {
"prefix": " tun "
}
}
},
"battery": { "battery": {
"states": { "states": {
"charged": { "charged": {
"suffix": " full ",
"fg": "#002b36", "fg": "#002b36",
"bg": "#859900" "bg": "#859900"
}, },
"AC": { "AC": {
"suffix": " ac ",
"fg": "#002b36", "fg": "#002b36",
"bg": "#859900" "bg": "#859900"
},
"charging": {
"suffix": " chr "
},
"discharging-10": {
"prefix": " ! ",
"suffix": " dis "
},
"discharging-25": {
"suffix": " dis "
},
"discharging-50": {
"suffix": " dis "
},
"discharging-80": {
"suffix": " dis "
},
"discharging-100": {
"suffix": " dis "
} }
} }
},
"caffeine": {
"states": { "activated": {"prefix": " caf on " }, "deactivated": { "prefix": " caf off " } }
}
} }