diff --git a/completions/bash/wpg b/completions/bash/wpg index 7e232a50..69d952f7 100644 --- a/completions/bash/wpg +++ b/completions/bash/wpg @@ -1,25 +1,25 @@ function _wpg() { - local optforprofiles + local optforcolorschemes _get_comp_words_by_ref cur # themes - optforprofiles="-s -e -d -z -m -LA -A --brt --sat" + optforcolorschemes="-s -e -d -z -m -LA -A --brt --sat -R" # themes, pywal themes optforvariabletheme="-Ti" # themes, filenames optvariable="-i -o" # filenames - optfordefault="-y -a -xa -ax" + optfordefault="--link -aL -La -a -ta -at --update" # templates - optfortemplates="-xd -dx" + optfortemplates="-td -dt" # pywal backends optforbackends="--backends" # pywal themes - optforthemes="--pywal" + optforthemes="--theme" if [[ $COMP_CWORD = 1 ]]; then COMPREPLY=($(compgen -W "$(_parse_usage wpg)" -- "$cur")) elif [[ $COMP_CWORD < 4 || ${COMP_WORDS[1]} != "-s" ]]; then - for opt in $optforprofiles; do + for opt in $optforcolorschemes; do if [[ $opt = ${COMP_WORDS[1]} ]]; then COMPREPLY=($(compgen -W "$(wpg -l)" -- "$cur")) fi @@ -31,7 +31,7 @@ function _wpg() { done for opt in $optforthemes; do if [[ $opt = ${COMP_WORDS[1]} ]]; then - COMPREPLY=($(compgen -W "$(wpg --pywal)" -- "$cur")) + COMPREPLY=($(compgen -W "$(wpg --theme)" -- "$cur")) fi done for opt in $optvariable; do @@ -45,7 +45,7 @@ function _wpg() { if [[ $opt = ${COMP_WORDS[1]} && $COMP_CWORD < 3 ]]; then COMPREPLY=($(compgen -W "$(wpg -l)" -- "$cur")) elif [[ $opt = ${COMP_WORDS[1]} ]]; then - COMPREPLY=($(compgen -W "$(wpg --pywal)" -- "$cur")) + COMPREPLY=($(compgen -W "$(wpg --theme)" -- "$cur")) fi done for opt in $optfordefault; do @@ -55,7 +55,7 @@ function _wpg() { done for opt in $optfortemplates; do if [[ $opt = ${COMP_WORDS[1]} ]]; then - COMPREPLY=($(compgen -W "$(wpg -xl)" -- "$cur")) + COMPREPLY=($(compgen -W "$(wpg -tl)" -- "$cur")) fi done fi diff --git a/completions/zsh/_wpg b/completions/zsh/_wpg index 3821302e..afa3a610 100644 --- a/completions/zsh/_wpg +++ b/completions/zsh/_wpg @@ -1,15 +1,15 @@ #compdef wpg -_profiles() { - local -a profiles - profiles=(`wpg -l`) - _describe 'profiles' profiles +_colorschemes() { + local -a colorschemes + colorschemes=(`wpg -l`) + _describe 'colorschemes' colorschemes } _templates() { - local -a templates - templates=(`wpg -xl`) - _describe 'templates' templates + local -a templates + templates=(`wpg -tl`) + _describe 'templates' templates } _backends() { @@ -20,52 +20,52 @@ _backends() { _themes() { local -a themes - themes=(`wpg --pywal`) + themes=(`wpg --theme`) _describe 'themes' themes } _wpg() { - local state optforprofiles + local state optforcolorschemes # themes - optforprofiles=(-s -e -d -z -m -A -LA --brt --sat) + optforcolorschemes=(-s -e -d -z -m -A -LA --brt --sat -R) # themes, filenames optvariable=(-i -o) # themes, pywal themes optvariabletheme=(-Ti) # filenames - optforgeneric=(-y -a -xa) + optforgeneric=(--link -a -La -aL -ta -at --update) # templates - optfortemplates=(-xd -dx) + optfortemplates=(-td -dt) # pywal backends optforbackends=(--backend) # pywal themes - optforthemes=(--pywal) + optforthemes=(--theme) _arguments \ '1: :->generic' \ - '*: :->listprofiles' + '*: :->listcolorschemes' case $state in (generic) _gnu_generic ;; - (listprofiles) + (listcolorschemes) if [[ $CURRENT < 5 || ${words[2]} != "-s" ]]; then - for opt in $optforprofiles; do + for opt in $optforcolorschemes; do if [[ $opt = ${words[2]} ]]; then - _profiles + _colorschemes fi done for opt in $optvariable; do if [[ $opt = ${words[2]} && $CURRENT < 4 ]]; then - _profiles + _colorschemes elif [[ $opt = ${words[2]} ]]; then _gnu_generic fi done for opt in $optvariabletheme; do if [[ $opt = ${words[2]} && $CURRENT < 4 ]]; then - _profiles + _colorschemes elif [[ $opt = ${words[2]} ]]; then _themes fi @@ -90,9 +90,9 @@ _wpg() { _themes fi done - fi - ;; - esac + fi + ;; + esac } _wpg "$@" diff --git a/setup.py b/setup.py index 28c92ec9..db12dce0 100644 --- a/setup.py +++ b/setup.py @@ -44,7 +44,7 @@ python_requires=">=3.5", install_requires=[ 'Pillow>=4.2.1', - 'pywal>=2.0.0', + 'pywal>=3.0.0', ], include_package_data=True, data_files=[('etc/wpgtk', ['wpgtk/misc/wpg.conf']), diff --git a/wpgtk/__main__.py b/wpgtk/__main__.py index 68dffc8b..7508ed88 100755 --- a/wpgtk/__main__.py +++ b/wpgtk/__main__.py @@ -5,19 +5,22 @@ import argparse import glob from os import path -from subprocess import Popen from .data import files from .data import themer from .data import color from .data import util from .data import sample -from .data.config import OPT_DIR, WPG_DIR, __version__ +from .data.config import OPT_DIR, __version__ from .data.config import settings def read_args(args): parser = argparse.ArgumentParser() + parser.add_argument("--version", + help="print the current version", + action="store_true") + parser.add_argument("-a", help="add a wallpaper and generate a colorscheme", nargs="+") @@ -26,75 +29,77 @@ def read_args(args): help="delete the wallpaper(s) from wallpaper folder", nargs="+") + parser.add_argument("-t", + help="add, remove and list templates instead " + "of themes", + action="store_true") + parser.add_argument("-s", help="set the wallpaper and/or colorscheme", nargs="+") - parser.add_argument("-m", - help="pick a random wallpaper/colorscheme", - action="store_true") - parser.add_argument('-l', help="see which wallpapers are available", action="store_true") parser.add_argument("-n", - help="don't change wallpaper", - action="store_true") - - parser.add_argument("-r", - help="restore the wallpaper and colorscheme", + help="avoid setting a wallpaper", action="store_true") - parser.add_argument("--version", - help="print the current version", + parser.add_argument("-m", + help="pick a random wallpaper/colorscheme", action="store_true") parser.add_argument("-c", help="shows the current wallpaper", action="store_true") + parser.add_argument("-z", + help="shuffles the given colorscheme(s)", + nargs="+") + + parser.add_argument("-A", + help="auto-adjusts the given colorscheme(s)", + nargs="+") + + parser.add_argument("-r", + help="restore the wallpaper and colorscheme", + action="store_true") + parser.add_argument("-L", "--light", help="temporarily enable light themes", action="store_true") + parser.add_argument("--theme", + help="list included pywal themes " + "or replace your current colorscheme with a " + "selection of your own", + const="list", nargs="?") + parser.add_argument("-T", help="assign a pywal theme to specific wallpaper" " instead of a json file", action="store_true") - parser.add_argument("-t", - help="send color sequences to all " - "terminals (deprecated)", - action="store_true") - - parser.add_argument("-x", - help="add, remove and list templates instead " - "of themes", - action="store_true") - - parser.add_argument("-z", - help="shuffles the given colorscheme(s)", - nargs="+") - - parser.add_argument("-A", - help="auto-adjusts the given colorscheme(s)", - nargs="+") - parser.add_argument("-i", help="import a theme in json format and asign " "to wallpaper [wallpaper, json]", nargs=2) + parser.add_argument("-o", help="export a theme in json " "format [wallpaper, json]", nargs="+") - parser.add_argument("-y", - help="link config file to template backup" - "[config, basefile]", + parser.add_argument("-R", + help="reset template(s) to their original colors", nargs="+") + parser.add_argument("--link", + help="link config file to template backup " + "[.base, config]", + nargs=2) + parser.add_argument("--sat", help="add or substract the saturation of a " "colorscheme [colorscheme, sat] (0, 1)", @@ -113,17 +118,20 @@ def read_args(args): help="set a one time alpha value", nargs=1) - parser.add_argument("--pywal", - help="list included pywal themes " - "or replace your current colorscheme with a " - "selection of your own", - const="list", nargs="?") + parser.add_argument("--preview", + help="preview your current colorscheme", + action="store_true") + + parser.add_argument("--update", + help="update template(s) of your choice " + "to the new format", + nargs="+") return parser.parse_args() def process_arg_errors(args): - if args.m and args.s: + if args.m and (args.s or args.R): logging.error("invalid combination of flags") exit(1) @@ -135,15 +143,7 @@ def process_arg_errors(args): logging.error("specify at most 2 filenames") exit(1) - if args.y and len(args.y) != 2: - logging.error("specify a config and a basefile") - exit(1) - - if args.i and len(args.i) != 2: - logging.error("specify a wallpaper and a colorscheme json") - exit(1) - - if args.o and len(args.o) != 2: + if args.o and (len(args.o) < 1 or len(args.o) > 2): logging.error("specify wallpaper and optionally an output path") exit(1) @@ -158,11 +158,20 @@ def process_args(args): if args.alpha: settings["alpha"] = args.alpha[0] - if args.m: - filename = random.choice(files.get_file_list()) - themer.set_theme(filename, filename, args.r) + if args.preview: + pywal.colors.palette() exit(0) + if args.m: + file_list = files.get_file_list() + if len(file_list) > 0: + filename = random.choice(file_list) + themer.set_theme(filename, filename, args.r) + exit(0) + else: + logging.error("you have no themes") + exit(1) + if args.s: if len(args.s) == 1: themer.set_theme(args.s[0], args.s[0], args.r) @@ -171,29 +180,30 @@ def process_args(args): exit(0) if args.l: - if args.x: + if args.t: templates = files.get_file_list(OPT_DIR, False) any(print(t) for t in templates if ".base" in t) else: print("\n".join(files.get_file_list())) exit(0) - if args.t: - Popen(["cat", path.join(WPG_DIR, "sequences")]) - exit(0) - if args.version: print("current version: " + __version__) exit(0) if args.d: - delete_action = files.delete_template if args.x \ + delete_action = files.delete_template if args.t \ else themer.delete_theme - any(delete_action(x) for x in args.d) + try: + any(delete_action(x) for x in args.d) + except IOError: + logging.error("file not found") + exit(1) + exit(0) if args.a: - add_action = files.add_template if args.x \ + add_action = files.add_template if args.t \ else themer.create_theme for x in args.a: if path.isfile(glob.glob(x)[0]): @@ -218,8 +228,8 @@ def process_args(args): logging.info("shuffled %s" % arg) exit(0) - if args.y: - files.add_template(args.y[0], args.y[1]) + if args.link: + files.add_template(args.link[1], args.link[0]) exit(0) if args.i: @@ -230,7 +240,15 @@ def process_args(args): themer.export_theme(*args.o) exit(0) - if args.pywal == "list": + if args.R: + try: + any(themer.reset_theme(arg) for arg in args.R) + except IOError: + logging.error("file not found") + exit(1) + exit(0) + + if args.theme == "list": name_dic = pywal.theme.list_themes() name_list = [t.name.replace(".json", "") for t in name_dic] print("\n".join(name_list)) @@ -254,14 +272,20 @@ def process_args(args): sample.create_sample(cl, files.get_sample_path(args.brt[0])) exit(0) - if args.pywal and args.pywal != "list": - themer.set_pywal_theme(args.pywal) + if args.theme and args.theme != "list": + themer.set_pywal_theme(args.theme) exit(0) if args.backend == "list": print("\n".join(pywal.colors.list_backends())) exit(0) + if args.update: + for arg in args.update: + if arg.endswith(".base"): + files.update_template(arg) + exit(0) + if args.backend and args.backend != "list": if args.backend in pywal.colors.list_backends(): settings['backend'] = args.backend @@ -280,8 +304,10 @@ def main(): try: _gui = __import__("wpgtk.gui.theme_picker", fromlist=['theme_picker']) _gui.run(args) + exit(0) except NameError: logging.error("missing pygobject module, use cli") + exit(1) if __name__ == "__main__": diff --git a/wpgtk/data/color.py b/wpgtk/data/color.py index 0ea90ec0..7dd96e31 100755 --- a/wpgtk/data/color.py +++ b/wpgtk/data/color.py @@ -2,6 +2,8 @@ import logging import pywal import os +import re +import threading from operator import itemgetter from subprocess import Popen from random import shuffle, randint @@ -13,13 +15,16 @@ from . import sample -def get_pywal_dict(wallpaper): +def get_pywal_dict(wallpaper, is_file=False): """get the color dictionary of a given wallpaper""" + light_theme = settings.getboolean("light_theme", False) pywal.util.Color.alpha_num = settings.get("alpha", "100") + image = pywal.image.get(os.path.join(WALL_DIR, wallpaper)) return pywal.colors.get( image, + light=(is_file and light_theme), backend=settings.get("backend", "wal"), cache_dir=WPG_DIR ) @@ -28,6 +33,8 @@ def get_pywal_dict(wallpaper): def get_color_list(filename, json=False): """extract a list with 16 colors from a json or a pywal dict""" is_new = not os.path.isfile(files.get_cache_path(filename)) + auto_adjust = settings.getboolean("auto_adjust", True) + light_theme = settings.getboolean("light_theme", False) if json: theme = pywal.util.read_file_json(filename) @@ -40,6 +47,8 @@ def get_color_list(filename, json=False): color_list = list(theme["colors"].values()) if is_new and not json: + if auto_adjust or light_theme: + color_list = auto_adjust_colors(color_list) sample.create_sample(color_list, files.get_sample_path(filename)) write_colors(filename, color_list) @@ -81,27 +90,21 @@ def change_colors(colors, which): if which in FILE_DIC: which = FILE_DIC[which] - tmp_filename = which + ".base" try: - with open(tmp_filename, "r") as tmp_file: + with open("%s.base" % which, "r") as tmp_file: first_line = tmp_file.readline() - tmp_file.seek(0) - tmp_data = tmp_file.read() - - if "wpgtk-ignore" not in first_line: - for k, v in user_keywords.items(): - tmp_data = tmp_data.replace(util.build_key(k), v) - for k, v in {**colors["wpgtk"], **colors["colors"]}.items(): - tmp_data = tmp_data.replace(util.build_key(k.upper()), v.strip("#")) + if "wpgtk-ignore" not in first_line: + tmp_file.seek(0) + tmp_data = tmp_file.read() + tmp_data = tmp_data.format_map(colors) - if colors["icons"] and opt == "icon-step1": - for k, v in colors["icons"].items(): - tmp_data = tmp_data.replace(k, v.strip("#")) + with open(which, "w") as target_file: + target_file.write(tmp_data) + logging.info("wrote: %s" % opt.split("/").pop()) - with open(which, "w") as target_file: - target_file.write(tmp_data) - logging.info("wrote: %s" % opt.split("/").pop()) + except KeyError as e: + logging.error("%s in %s - key does not exist" % (e, opt)) except IOError: logging.error("%s - base file does not exist" % opt) @@ -111,7 +114,7 @@ def smart_sort(colors): """automatically set the most look-alike colors to their corresponding place in the standar xterm colors""" colors = colors[:8] - sorted_by_color = [] + sorted_by_color = list() base_colors = ["#000000", "#ff0000", "#00ff00", "#ffff00", "#0000ff", "#ff00ff", "#00ffff", "#ffffff"] @@ -154,7 +157,7 @@ def auto_adjust_colors(clist): if light == is_dark_theme(clist): clist[7], clist[0] = clist[0], clist[7] - comment = [alter_brightness(clist[0], sign * 20)] + comment = [alter_brightness(clist[0], sign * 25)] fg = [alter_brightness(clist[7], sign * 60)] clist = clist[:8] + comment \ + [alter_brightness(x, sign * get_hls_val(x, "light") * 0.3, added_sat) @@ -163,33 +166,6 @@ def auto_adjust_colors(clist): return clist -def add_icon_colors(colors): - try: - glyph = util.alter_brightness(colors["wpgtk"]["COLORIN"], -15) - icon_dic = {} - - with open(FILE_DIC["icon-step1"], "r") as icon_file: - for line in icon_file: - if("glyphColorNew=" in line): - icon_dic["oldglyph"] = line.split("=")[1].strip("\n") - - if("frontColorNew=" in line): - icon_dic["oldfront"] = line.split("=")[1].strip("\n") - - if("backColorNew=" in line): - icon_dic["oldback"] = line.split("=")[1].strip("\n") - - icon_dic["newglyph"] = glyph - icon_dic["newfront"] = colors["wpgtk"]["COLORACT"] - icon_dic["newback"] = colors["wpgtk"]["COLORIN"] - - return icon_dic - - except IOError: - logging.error("icons - base file does not exists") - return - - def change_templates(colors): """call change_colors on each custom template installed or defined by the user""" @@ -199,45 +175,95 @@ def change_templates(colors): try: for template in templates: original = template.split(".base").pop(0) - change_colors(colors, os.path.join(OPT_DIR, original)) + args = (colors, os.path.join(OPT_DIR, original)) + t = threading.Thread(target=change_colors, args=args) + t.start() except Exception as e: logging.error(str(e)) logging.error("optional file " + original, file=sys.stderr) -def split_active(hexc, is_dark_theme=True): +def add_icon_colors(colors): + try: + icon_dic = dict() + entry = re.compile(r"(.*)=(.*)$") + + with open(FILE_DIC["icon-step1"], "r") as icon_file: + for line in icon_file: + match = entry.search(line) + if match: + icon_dic[match.group(1)] = match.group(2) + + icon_dic["oldglyph"] = icon_dic["newglyph"] + icon_dic["oldfront"] = icon_dic["newfront"] + icon_dic["oldback"] = icon_dic["newback"] + + return icon_dic + + except KeyError: + logging.error("icons - badly formatted base file for icons") + return dict() + + except IOError: + logging.error("icons - base file does not exists") + return dict() + + +def wpgtk_colors(hexc, is_dark_theme=True): """extract active and inactive colors from a given hex color value""" brightness = util.get_hls_val(hexc, "light") - if is_dark_theme: - return {"COLORACT": util.alter_brightness(hexc, brightness * -0.20), - "COLORIN": util.alter_brightness(hexc, brightness * -0.45)} - else: - return {"COLORACT": util.alter_brightness(hexc, brightness * 0.30), - "COLORIN": hexc} + active = util.alter_brightness(hexc, brightness * -0.20) \ + if is_dark_theme else util.alter_brightness(hexc, brightness * 0.30) + + inactive = util.alter_brightness(hexc, brightness * -0.45) \ + if is_dark_theme else hexc + return { + "active": active, + "inactive": inactive, + "newfront": active, + "newback": inactive, + "newglyph": util.alter_brightness(inactive, -15) + } -def add_wpgtk_colors(cdic): + +def get_color_dict(cdic): """ensamble wpgtk color dictionary""" index = settings.getint("active") index = index if index > 0 else randint(9, 14) base_color = cdic["colors"]["color%s" % index] - color_list = list(cdic["colors"].values()) - cdic["wpgtk"] = split_active(base_color, is_dark_theme(color_list)) - cdic["icons"] = add_icon_colors(cdic) - return cdic + all_colors = { + "wallpaper": cdic["wallpaper"], + "alpha": cdic["alpha"], + **cdic["special"], + **cdic["colors"], + **add_icon_colors(cdic), + **wpgtk_colors(base_color, is_dark_theme(color_list)) + } + + try: + user_words = {k: v.format(**all_colors) + for k, v in user_keywords.items()} + all_colors = {**all_colors, **user_words} + + except KeyError as e: + logging.error("%s - invalid, use double {{}} " + "to escape curly braces" % e) + + return {k: pywal.util.Color(v) for k, v in all_colors.items()} def apply_colorscheme(colors): - colors = add_wpgtk_colors(colors) + color_dict = get_color_dict(colors) if os.path.isfile(FILE_DIC["icon-step2"]): - change_colors(colors, "icon-step1") + change_colors(color_dict, "icon-step1") Popen(FILE_DIC["icon-step2"]) - change_templates(colors) + change_templates(color_dict) diff --git a/wpgtk/data/config.py b/wpgtk/data/config.py index 7cf25b3a..df1209e0 100644 --- a/wpgtk/data/config.py +++ b/wpgtk/data/config.py @@ -3,7 +3,7 @@ import os import logging -__version__ = '5.8.7' +__version__ = '6.0.0' parser = None diff --git a/wpgtk/data/files.py b/wpgtk/data/files.py index 6f1112e3..1832f08a 100644 --- a/wpgtk/data/files.py +++ b/wpgtk/data/files.py @@ -26,10 +26,24 @@ def get_file_list(path=WALL_DIR, images=True): return files +def write_script(wallpaper, colorscheme): + """writes the script that should be called on startup + to restore the theme.""" + set_wall = settings.getboolean("set_wallpaper", True) + light_theme = settings.getboolean("light_theme", True) + + flags = "-rs" if set_wall else "-nrs" + flags += "L" if light_theme else "" + + with open(join(WPG_DIR, "wp_init.sh"), "w") as script: + command = "wpg %s '%s' '%s'" % (flags, wallpaper, colorscheme) + script.writelines(["#!/usr/bin/env bash\n", command]) + + def get_cache_path(wallpaper, backend=None): """get a colorscheme cache path using a wallpaper name""" if not backend: - backend = settings.get('backend', 'wal') + backend = settings.get("backend", "wal") filepath = join(WALL_DIR, wallpaper) filename = cache_fname(filepath, backend, False, WPG_DIR) @@ -40,7 +54,7 @@ def get_cache_path(wallpaper, backend=None): def get_sample_path(wallpaper, backend=None): """gets a wallpaper colorscheme sample's path""" if not backend: - backend = settings.get('backend', 'wal') + backend = settings.get("backend", "wal") sample_filename = "%s_%s_sample.png" % (wallpaper, backend) @@ -97,6 +111,32 @@ def delete_colorschemes(wallpaper): pass +def update_color(matchobj): + if matchobj.group(1): + return "{%s}" % matchobj.group(1).lower() + + +def update_template(template_path): + tmp_data = "" + + with open(template_path, "r") as f: + tmp_data = f.read() + + logging.info("escaping legitimate curly braces {} -> {{}}") + tmp_data = tmp_data.replace("{", "{{") + tmp_data = tmp_data.replace("}", "}}") + + logging.info("replacing # with braces {colorxx}") + tmp_data = re.sub(r"#<(COLOR[0-9]{1,2})>", update_color, tmp_data) + tmp_data = tmp_data.replace("#", "{active}") + tmp_data = tmp_data.replace("#", "{inactive}") + + with open(template_path, "w") as f: + logging.info("writting %s" % template_path) + f.write(tmp_data) + logging.info("%s update complete" % template_path) + + def change_current(filename): """update symlink to point to the current wallpaper""" os.symlink(join(WALL_DIR, filename), join(WPG_DIR, ".currentTmp")) diff --git a/wpgtk/data/reload.py b/wpgtk/data/reload.py index 31aa9d3b..d7ea0e13 100644 --- a/wpgtk/data/reload.py +++ b/wpgtk/data/reload.py @@ -6,7 +6,7 @@ from pywal import reload from . import util -from .config import FORMAT_DIR, HOME +from .config import FORMAT_DIR, HOME, settings def xrdb(): @@ -36,7 +36,7 @@ def openbox(): def gtk3(): - if shutil.which("xsettingsd"): + if shutil.which("xsettingsd") and settings.getboolean("gtk", True): fd, path = tempfile.mkstemp() try: with os.fdopen(fd, 'w+') as tmp: @@ -56,8 +56,11 @@ def all(): tint2() dunst() openbox() - gtk3() reload.i3() reload.polybar() reload.gtk() + reload.kitty() reload.sway() + + if settings.getboolean("gtk", True): + gtk3() diff --git a/wpgtk/data/themer.py b/wpgtk/data/themer.py index 054fc610..441e5864 100644 --- a/wpgtk/data/themer.py +++ b/wpgtk/data/themer.py @@ -30,8 +30,11 @@ def create_theme(filepath): def set_theme(wallpaper, colorscheme, restore=False): """apply a given wallpaper and a given colorscheme""" + is_file = path.isdir(colorscheme) or path.isfile(colorscheme) + target = colorscheme if is_file else path.join(WALL_DIR, colorscheme) + set_wall = settings.getboolean("set_wallpaper", True) - colors = color.get_pywal_dict(path.join(WALL_DIR, colorscheme)) + colors = color.get_pywal_dict(target, is_file) pywal.sequences.send(colors, WPG_DIR) if not restore: @@ -44,28 +47,19 @@ def set_theme(wallpaper, colorscheme, restore=False): set_wall = filepath if path.isfile(filepath) else colors["wallpaper"] pywal.wallpaper.change(set_wall) - flags = "-rs" if set_wall else "-nrs" - with open(path.join(WPG_DIR, "wp_init.sh"), "w") as script: - script.writelines(["#!/usr/bin/env bash\n", - "wpg %s '%s' '%s'" % - (flags, wallpaper, colorscheme)]) + files.write_script(wallpaper, colorscheme) + files.change_current(wallpaper) Popen(['chmod', '+x', path.join(WPG_DIR, "wp_init.sh")]) reload.xrdb() - files.change_current(wallpaper) - if settings.getboolean('execute_cmd'): Popen(['bash', '-c', settings['command']]) def delete_theme(filename): - try: - remove(path.join(WALL_DIR, filename)) - files.delete_colorschemes(filename) - except IOError as e: - logging.error("file not available") - logging.error(e.message) + remove(path.join(WALL_DIR, filename)) + files.delete_colorschemes(filename) def get_current(): @@ -73,6 +67,14 @@ def get_current(): return image +def reset_theme(theme_name): + """restore a colorscheme to it's original state by deleting + and re adding the image""" + wallpaper = realpath(path.join(WALL_DIR, theme_name)) + delete_theme(theme_name) + create_theme(wallpaper) + + def import_theme(wallpaper, json_file, theme=False): """import a colorscheme from a JSON file either in terminal.sexy or pywal format""" diff --git a/wpgtk/data/util.py b/wpgtk/data/util.py index cc767a88..e0445089 100644 --- a/wpgtk/data/util.py +++ b/wpgtk/data/util.py @@ -62,13 +62,9 @@ def setup_log(): " %(module)-13s %(message)s", level=logging.INFO, stream=sys.stdout) - logging.addLevelName(logging.ERROR, "err") - logging.addLevelName(logging.INFO, "inf") - logging.addLevelName(logging.WARNING, "wrn") - - -def build_key(keyword): - return "<{}>".format(keyword) + logging.addLevelName(logging.ERROR, "e") + logging.addLevelName(logging.INFO, "i") + logging.addLevelName(logging.WARNING, "w") def get_pid(name): diff --git a/wpgtk/gui/color_grid.py b/wpgtk/gui/color_grid.py index 027d7fca..ab7b1595 100644 --- a/wpgtk/gui/color_grid.py +++ b/wpgtk/gui/color_grid.py @@ -7,6 +7,7 @@ from ..data import util from ..data import files from ..data import sample +from ..data import themer from .color_picker import ColorDialog from gi import require_version @@ -63,6 +64,11 @@ def __init__(self, parent): self.button_grid.set_column_spacing(PAD) self.button_grid.set_row_spacing(PAD) + self.combo_grid = Gtk.Grid() + self.combo_grid.set_column_homogeneous(1) + self.combo_grid.set_column_spacing(PAD) + self.combo_grid.set_row_spacing(PAD) + self.color_list = ['000000']*16 self.button_list = [Gtk.Button('000000') for x in range(16)] self.selected_file = "" @@ -103,6 +109,10 @@ def __init__(self, parent): self.auto_button.connect("pressed", self.on_auto_click) self.auto_button.set_sensitive(False) + self.reset_button = Gtk.Button("Reset") + self.reset_button.set_sensitive(False) + self.reset_button.connect("pressed", self.on_reset_click) + self.done_lbl = Gtk.Label("") option_list = Gtk.ListStore(str) @@ -115,10 +125,13 @@ def __init__(self, parent): self.option_combo.set_entry_text_column(0) self.option_combo.connect("changed", self.combo_box_change) - self.button_grid.attach(self.import_button, 0, 0, 3, 1) - self.button_grid.attach(self.ok_button, 0, 1, 1, 1) - self.button_grid.attach(self.auto_button, 1, 1, 1, 1) - self.button_grid.attach(self.shuffle_button, 2, 1, 1, 1) + self.combo_grid.attach(self.option_combo, 0, 0, 3, 1) + self.combo_grid.attach(self.reset_button, 3, 0, 1, 1) + + self.button_grid.attach(self.ok_button, 0, 0, 1, 1) + self.button_grid.attach(self.auto_button, 1, 0, 1, 1) + self.button_grid.attach(self.shuffle_button, 2, 0, 1, 1) + self.button_grid.attach(self.import_button, 3, 0, 1, 1) self.sat_light_grid.attach(self.sat_lbl, 0, 0, 1, 1) self.sat_light_grid.attach(self.sat_red, 1, 0, 1, 1) @@ -128,7 +141,7 @@ def __init__(self, parent): self.sat_light_grid.attach(self.light_red, 4, 0, 1, 1) self.sat_light_grid.attach(self.light_add, 5, 0, 1, 1) - self.attach(self.option_combo, 0, 0, 1, 1) + self.attach(self.combo_grid, 0, 0, 1, 1) self.attach(self.button_grid, 0, 1, 1, 1) self.attach(self.colorgrid, 0, 2, 1, 1) self.attach(self.sample, 0, 3, 1, 1) @@ -147,6 +160,26 @@ def render_buttons(self): button.modify_bg(Gtk.StateType.NORMAL, gcolor) button.modify_fg(Gtk.StateType.NORMAL, fgcolor) + def render_theme(self): + sample_path = files.get_sample_path(self.selected_file) + + try: + self.color_list = color.get_color_list(self.selected_file) + except SystemExit: + self.color_list = themer.set_fallback_theme(self.selected_file) + self.render_buttons() + + try: + self.pixbuf_sample = GdkPixbuf.Pixbuf\ + .new_from_file_at_size(sample_path, width=500, height=300) + except: + sample.create_sample(self.color_list, sample_path) + self.pixbuf_sample = GdkPixbuf.Pixbuf\ + .new_from_file_at_size(sample_path, width=500, height=300) + + self.sample.set_from_pixbuf(self.pixbuf_sample) + self.parent.sample.set_from_pixbuf(self.pixbuf_sample) + def hls_change(self, widget, *gparam): if gparam[0] == "sat": val = 0.05 if gparam[1] == "add" else -0.05 @@ -157,10 +190,10 @@ def hls_change(self, widget, *gparam): self.color_list = [util.alter_brightness(x, val, 0) for x in self.color_list] self.render_buttons() - sample.create_sample(self.color_list) self.render_sample() def render_sample(self): + sample.create_sample(self.color_list) sample_path = os.path.join(WALL_DIR, ".tmp.sample.png") self.pixbuf_sample = GdkPixbuf.Pixbuf.new_from_file_at_size( str(sample_path), @@ -194,9 +227,12 @@ def on_ok_click(self, widget): def on_auto_click(self, widget): self.color_list = color.auto_adjust_colors(self.color_list) self.render_buttons() - sample.create_sample(self.color_list) self.render_sample() + def on_reset_click(self, widget): + themer.reset_theme(self.selected_file) + self.render_theme() + def on_import_click(self, widget): fcd = Gtk.FileChooserDialog( 'Select a colorscheme', self.parent, @@ -213,14 +249,12 @@ def on_import_click(self, widget): if response == Gtk.ResponseType.OK: self.color_list = color.get_color_list(fcd.get_filename(), True) self.render_buttons() - sample.create_sample(self.color_list[:]) self.render_sample() fcd.destroy() def on_shuffle_click(self, widget): self.color_list = color.shuffle_colors(self.color_list) self.render_buttons() - sample.create_sample(self.color_list) self.render_sample() def on_color_click(self, widget): @@ -240,14 +274,15 @@ def on_color_click(self, widget): if util.get_hls_val(hex_color, 'light') < 100: fgcolor = Gdk.color_parse('#FFFFFF') else: - fgcolor = Gdk.color_parse('#101010') + fgcolor = Gdk.color_parse('#000000') + widget.set_sensitive(True) widget.modify_bg(Gtk.StateType.NORMAL, gcolor) widget.modify_fg(Gtk.StateType.NORMAL, fgcolor) + for i, c in enumerate(self.button_list): if c.get_label() != self.color_list[i]: self.color_list[i] = c.get_label() - sample.create_sample(self.color_list) self.render_sample() dialog.destroy() @@ -261,21 +296,10 @@ def combo_box_change(self, widget): self.import_button.set_sensitive(True) self.light_add.set_sensitive(True) self.light_red.set_sensitive(True) + self.reset_button.set_sensitive(True) self.sat_add.set_sensitive(True) self.sat_red.set_sensitive(True) current_walls = files.get_file_list() self.selected_file = current_walls[x] - sample_path = files.get_sample_path(self.selected_file) - self.color_list = color.get_color_list(self.selected_file) - self.render_buttons() - - try: - self.pixbuf_sample = GdkPixbuf.Pixbuf\ - .new_from_file_at_size(sample_path, width=500, height=300) - self.sample.set_from_pixbuf(self.pixbuf_sample) - except: - sample.create_sample(self.color_list, sample_path) - - # Refresh parent's sample pixbuf - self.parent.sample.set_from_pixbuf(self.pixbuf_sample) + self.render_theme() diff --git a/wpgtk/gui/option_grid.py b/wpgtk/gui/option_grid.py index a511bca2..268b4e05 100644 --- a/wpgtk/gui/option_grid.py +++ b/wpgtk/gui/option_grid.py @@ -54,9 +54,11 @@ def __init__(self, parent): # Backend Combo self.backend_list = colors.list_backends() self.backend_lbl = Gtk.Label("Select your backend:") + be_store = Gtk.ListStore(str) for elem in self.backend_list: be_store.append([elem]) + self.backend_combo = Gtk.ComboBox.new_with_model(be_store) self.backend_combo.pack_start(self.renderer_text, True) self.backend_combo.add_attribute(self.renderer_text, 'text', 0) @@ -64,36 +66,42 @@ def __init__(self, parent): self.backend_combo.connect("changed", self.combo_box_change, "backend") # Switches - self.tint2_switch = Gtk.Switch() - self.tint2_switch.connect("notify::active", self.on_activate, "tint2") - self.lbl_tint2 = Gtk.Label("Reload Tint2") - self.gtk_switch = Gtk.Switch() self.gtk_switch.connect("notify::active", self.on_activate, "gtk") - self.lbl_gtk = Gtk.Label("Reload GTK2") - - self.openbox_switch = Gtk.Switch() - self.openbox_switch.connect("notify::active", - self.on_activate, "openbox") - self.lbl_openbox = Gtk.Label("Reload openbox") + self.lbl_gtk = Gtk.Label("Reload GTK+") self.light_theme_switch = Gtk.Switch() - self.light_theme_switch.connect("notify::active", - self.on_activate, "light_theme") + self.light_theme_switch.connect( + "notify::active", + self.on_activate, + "light_theme" + ) self.lbl_light_theme = Gtk.Label("Use Light Theme") self.wallpaper_switch = Gtk.Switch() - self.wallpaper_switch.connect("notify::active", - self.on_activate, - "set_wallpaper") + self.wallpaper_switch.connect( + "notify::active", + self.on_activate, + "set_wallpaper" + ) self.lbl_wallpaper = Gtk.Label("Set wallpaper") self.smart_sort_switch = Gtk.Switch() - self.smart_sort_switch.connect("notify::active", - self.on_activate, - "smart_sort") + self.smart_sort_switch.connect( + "notify::active", + self.on_activate, + "smart_sort" + ) self.lbl_smart_sort = Gtk.Label("Use smart sort") + self.auto_adjust_switch = Gtk.Switch() + self.auto_adjust_switch.connect( + "notify::active", + self.on_activate, + "auto_adjust" + ) + self.lbl_auto_adjust = Gtk.Label("Always auto adjust") + # edit cmd self.editor_lbl = Gtk.Label("Open optional files with:") self.editor_txt = Gtk.Entry() @@ -102,11 +110,16 @@ def __init__(self, parent): # cmd self.command_lbl = Gtk.Label("Run command after Colorize") self.command_exe_lbl = Gtk.Label("Command: ") + self.command_txt = Gtk.Entry() self.command_txt.connect("changed", self.on_txt_change, "command") + self.command_switch = Gtk.Switch() - self.command_switch.connect("notify::active", - self.on_activate, "execute_cmd") + self.command_switch.connect( + "notify::active", + self.on_activate, + "execute_cmd" + ) self.alpha_lbl = Gtk.Label('Alpha:') self.alpha_txt = Gtk.Entry() @@ -120,23 +133,18 @@ def __init__(self, parent): self.switch_grid.attach(self.lbl_gtk, 5, 1, 3, 1) self.switch_grid.attach(self.gtk_switch, 9, 1, 1, 1) + self.switch_grid.attach(self.lbl_auto_adjust, 5, 2, 3, 1) + self.switch_grid.attach(self.auto_adjust_switch, 9, 2, 1, 1) + self.switch_grid.attach(self.command_lbl, 1, 2, 3, 1) self.switch_grid.attach(self.command_switch, 4, 2, 1, 1) - self.switch_grid.attach(self.lbl_openbox, 5, 2, 3, 1) - self.switch_grid.attach(self.openbox_switch, 9, 2, 1, 1) - self.switch_grid.attach(self.lbl_light_theme, 1, 3, 3, 1) self.switch_grid.attach(self.light_theme_switch, 4, 3, 1, 1) - self.switch_grid.attach(self.lbl_tint2, 5, 3, 3, 1) - self.switch_grid.attach(self.tint2_switch, 9, 3, 1, 1) - self.switch_grid.attach(self.lbl_smart_sort, 1, 4, 3, 1) self.switch_grid.attach(self.smart_sort_switch, 4, 4, 1, 1) - # cmd Grid attach - # Active Grid attach self.active_grid.attach(self.backend_lbl, 1, 1, 1, 1) self.active_grid.attach(self.backend_combo, 2, 1, 1, 1) @@ -173,18 +181,16 @@ def load_opt_list(self): .set_active(settings.getint("active", 0)) self.gtk_switch\ .set_active(settings.getboolean("gtk", True)) - self.tint2_switch\ - .set_active(settings.getboolean("tint2", True)) self.command_switch\ .set_active(settings.getboolean("execute_cmd", False)) - self.openbox_switch\ - .set_active(settings.getboolean("openbox", True)) self.light_theme_switch\ .set_active(settings.getboolean("light_theme", False)) self.wallpaper_switch\ .set_active(settings.getboolean("set_wallpaper", True)) self.smart_sort_switch\ .set_active(settings.getboolean("smart_sort", True)) + self.auto_adjust_switch\ + .set_active(settings.getboolean("auto_adjust", False)) self.editor_txt\ .set_text(settings.get("editor", "urxvt -e vim")) diff --git a/wpgtk/misc/wpg-install.sh b/wpgtk/misc/wpg-install.sh index f04cf776..83c8c5d9 100755 --- a/wpgtk/misc/wpg-install.sh +++ b/wpgtk/misc/wpg-install.sh @@ -141,6 +141,7 @@ install_icons() { echo "Installing icon pack"; cp -r flattrcolor "${HOME}/.icons/" && \ + cp -r flattrcolor-dark "${HOME}/.icons/" && \ echo ":: flattr icons install done." } diff --git a/wpgtk/misc/wpg.conf b/wpgtk/misc/wpg.conf index c90050a9..d5f82ca2 100644 --- a/wpgtk/misc/wpg.conf +++ b/wpgtk/misc/wpg.conf @@ -1,15 +1,14 @@ [settings] set_wallpaper = true -openbox = true gtk = true active = 0 -tint2 = true light_theme = false editor = urxvt -e vim execute_cmd = false command = urxvt -e echo hi backend = wal alpha = 100 -auto_sort = true +smart_sort = true +auto_adjust = false [keywords]